{"version":3,"sources":["/home/runner/work/rivet/rivet/rivetkit-typescript/packages/workflow-engine/dist/tsup/chunk-KLHCG2KY.cjs","../../src/error-utils.ts","../../src/errors.ts","../../src/keys.ts","../../src/location.ts","../../schemas/serde.ts","../schemas/v1.ts","../../schemas/versioned.ts","../../src/storage.ts","../../src/context.ts","../../src/utils.ts","../../src/index.ts"],"names":["config"],"mappings":"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AACM,MAAA;AACP,IAAA;AAGsC,IAAA;AACtB,IAAA;AAC4B,IAAA;AAExC,IAAA;AACG,MAAA;AACL,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACD,MAAA;AACuB,IAAA;AACoB,MAAA;AACZ,QAAA;AAC/B,MAAA;AACM,MAAA;AACP,IAAA;AAEgB,IAAA;AAC4B,IAAA;AACJ,IAAA;AACJ,MAAA;AACxB,QAAA;AACT,UAAA;AAC6B,UAAA;AAC9B,QAAA;AACA,MAAA;AAKC,MAAA;AACsB,QAAA;AACxB,MAAA;AACD,IAAA;AAEM,IAAA;AACP,EAAA;AACD;AX0mGmH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/home/runner/work/rivet/rivet/rivetkit-typescript/packages/workflow-engine/dist/tsup/chunk-KLHCG2KY.cjs","sourcesContent":[null,"import type { WorkflowError, WorkflowErrorEvent } from \"./types.js\";\n\nconst WORKFLOW_ERROR_REPORTED_SYMBOL = Symbol(\"workflow.error.reported\");\n\n/**\n * Extract structured error information from an error.\n */\nexport function extractErrorInfo(error: unknown): WorkflowError {\n\tif (error instanceof Error) {\n\t\tconst result: WorkflowError = {\n\t\t\tname: error.name,\n\t\t\tmessage: error.message,\n\t\t\tstack: error.stack,\n\t\t};\n\n\t\tconst metadata: Record<string, unknown> = {};\n\t\tfor (const key of Object.keys(error)) {\n\t\t\tif (key !== \"name\" && key !== \"message\" && key !== \"stack\") {\n\t\t\t\tconst value = (error as unknown as Record<string, unknown>)[\n\t\t\t\t\tkey\n\t\t\t\t];\n\t\t\t\tif (\n\t\t\t\t\ttypeof value === \"string\" ||\n\t\t\t\t\ttypeof value === \"number\" ||\n\t\t\t\t\ttypeof value === \"boolean\" ||\n\t\t\t\t\tvalue === null\n\t\t\t\t) {\n\t\t\t\t\tmetadata[key] = value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (Object.keys(metadata).length > 0) {\n\t\t\tresult.metadata = metadata;\n\t\t}\n\n\t\treturn result;\n\t}\n\n\treturn {\n\t\tname: \"Error\",\n\t\tmessage: String(error),\n\t};\n}\n\n/**\n * Mark an error after it has been reported to the error hook.\n */\nexport function markErrorReported<T extends Error>(error: T): T {\n\t(\n\t\terror as T & {\n\t\t\t[WORKFLOW_ERROR_REPORTED_SYMBOL]?: boolean;\n\t\t}\n\t)[WORKFLOW_ERROR_REPORTED_SYMBOL] = true;\n\treturn error;\n}\n\n/**\n * Check if an error was already reported to the error hook.\n */\nexport function isErrorReported(error: unknown): boolean {\n\tif (!(error instanceof Error)) {\n\t\treturn false;\n\t}\n\n\treturn Boolean(\n\t\t(\n\t\t\terror as Error & {\n\t\t\t\t[WORKFLOW_ERROR_REPORTED_SYMBOL]?: boolean;\n\t\t\t}\n\t\t)[WORKFLOW_ERROR_REPORTED_SYMBOL],\n\t);\n}\n\n/**\n * Return the outer tag name for a workflow error event.\n */\nexport function getErrorEventTag(\n\tevent: WorkflowErrorEvent,\n): \"step\" | \"rollback\" | \"workflow\" {\n\tif (\"step\" in event) {\n\t\treturn \"step\";\n\t}\n\tif (\"rollback\" in event) {\n\t\treturn \"rollback\";\n\t}\n\treturn \"workflow\";\n}\n","/**\n * Thrown from steps to prevent retry.\n * Use this when an error is unrecoverable and retrying would be pointless.\n */\nexport class CriticalError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"CriticalError\";\n\t}\n}\n\n/**\n * Thrown from steps to force rollback without retry.\n */\nexport class RollbackError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"RollbackError\";\n\t}\n}\n\n/**\n * Thrown when rollback is used without a checkpoint.\n */\nexport class RollbackCheckpointError extends Error {\n\tconstructor() {\n\t\tsuper(\"Rollback requires a checkpoint before any rollback step\");\n\t\tthis.name = \"RollbackCheckpointError\";\n\t}\n}\n\n/**\n * Internal: Workflow should sleep until deadline.\n * This is thrown to yield control back to the scheduler.\n * Optionally, the workflow can also wake early if certain messages arrive.\n */\nexport class SleepError extends Error {\n\tconstructor(\n\t\tpublic readonly deadline: number,\n\t\tpublic readonly messageNames?: string[],\n\t) {\n\t\tsuper(\n\t\t\tmessageNames && messageNames.length > 0\n\t\t\t\t? `Sleeping until ${deadline} or messages: ${messageNames.join(\", \")}`\n\t\t\t\t: `Sleeping until ${deadline}`,\n\t\t);\n\t\tthis.name = \"SleepError\";\n\t}\n}\n\n/**\n * Internal: Workflow is waiting for messages.\n * This is thrown to yield control back to the scheduler.\n */\nexport class MessageWaitError extends Error {\n\tconstructor(public readonly messageNames: string[]) {\n\t\tsuper(`Waiting for messages: ${messageNames.join(\", \")}`);\n\t\tthis.name = \"MessageWaitError\";\n\t}\n}\n\n/**\n * Internal: Workflow was evicted.\n * This is thrown when the workflow is being gracefully stopped.\n */\nexport class EvictedError extends Error {\n\tconstructor() {\n\t\tsuper(\"Workflow evicted\");\n\t\tthis.name = \"EvictedError\";\n\t}\n}\n\n/**\n * Internal: Stop rollback traversal.\n */\nexport class RollbackStopError extends Error {\n\tconstructor() {\n\t\tsuper(\"Rollback traversal halted\");\n\t\tthis.name = \"RollbackStopError\";\n\t}\n}\n\n/**\n * Workflow code changed incompatibly.\n * Thrown when history doesn't match the current workflow code.\n */\nexport class HistoryDivergedError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"HistoryDivergedError\";\n\t}\n}\n\n/**\n * Step exhausted all retries.\n */\nexport class StepExhaustedError extends Error {\n\tconstructor(\n\t\tpublic readonly stepName: string,\n\t\tpublic readonly lastError?: string,\n\t) {\n\t\tsuper(\n\t\t\t`Step \"${stepName}\" exhausted retries: ${lastError ?? \"unknown error\"}`,\n\t\t);\n\t\tthis.name = \"StepExhaustedError\";\n\t}\n}\n\n/**\n * Step failed (will be retried).\n * Internal error used to trigger retry logic.\n */\nexport class StepFailedError extends Error {\n\tconstructor(\n\t\tpublic readonly stepName: string,\n\t\tpublic readonly originalError: unknown,\n\t\tpublic readonly attempts: number,\n\t\tpublic readonly retryAt: number,\n\t) {\n\t\tsuper(`Step \"${stepName}\" failed (attempt ${attempts})`);\n\t\tthis.name = \"StepFailedError\";\n\t\tthis.cause = originalError;\n\t}\n}\n\n/**\n * Join had branch failures.\n */\nexport class JoinError extends Error {\n\tconstructor(public readonly errors: Record<string, Error>) {\n\t\tsuper(`Join failed: ${Object.keys(errors).join(\", \")}`);\n\t\tthis.name = \"JoinError\";\n\t}\n}\n\n/**\n * Race had all branches fail.\n */\nexport class RaceError extends Error {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic readonly errors: Array<{ name: string; error: string }>,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"RaceError\";\n\t}\n}\n\n/**\n * Branch was cancelled (used by race).\n */\nexport class CancelledError extends Error {\n\tconstructor() {\n\t\tsuper(\"Branch cancelled\");\n\t\tthis.name = \"CancelledError\";\n\t}\n}\n\n/**\n * Entry is currently being processed.\n * Thrown when user forgets to await a step.\n */\nexport class EntryInProgressError extends Error {\n\tconstructor() {\n\t\tsuper(\n\t\t\t\"Cannot start a new workflow entry while another is in progress. \" +\n\t\t\t\t\"Did you forget to await the previous step/loop/sleep?\",\n\t\t);\n\t\tthis.name = \"EntryInProgressError\";\n\t}\n}\n","/**\n * Binary key encoding/decoding using fdb-tuple.\n * All keys are encoded as tuples with integer prefixes for proper sorting.\n */\n\nimport * as tuple from \"fdb-tuple\";\nimport type { Location, LoopIterationMarker, PathSegment } from \"./types.js\";\n\n// === Key Prefixes ===\n// Using integers for compact encoding and proper sorting\n\nexport const KEY_PREFIX = {\n\tNAMES: 1, // Name registry: [1, index]\n\tHISTORY: 2, // History entries: [2, ...locationSegments]\n\tWORKFLOW: 3, // Workflow metadata: [3, field]\n\tENTRY_METADATA: 4, // Entry metadata: [4, entryId]\n} as const;\n\n// Workflow metadata field identifiers\nexport const WORKFLOW_FIELD = {\n\tSTATE: 1,\n\tOUTPUT: 2,\n\tERROR: 3,\n\tINPUT: 4,\n} as const;\n\n// === Type Definitions ===\n\n// fdb-tuple's TupleItem type - we use a subset\ntype TupleItem = string | number | boolean | null | TupleItem[];\n\n// === Location Segment Encoding ===\n\n/**\n * Convert a path segment to tuple elements.\n * - NameIndex (number) → just the number\n * - LoopIterationMarker → nested tuple [loopIdx, iteration]\n */\nfunction segmentToTuple(segment: PathSegment): TupleItem {\n\tif (typeof segment === \"number\") {\n\t\treturn segment;\n\t}\n\t// LoopIterationMarker\n\treturn [segment.loop, segment.iteration];\n}\n\n/**\n * Convert tuple elements back to a path segment.\n */\nfunction tupleToSegment(element: TupleItem): PathSegment {\n\tif (typeof element === \"number\") {\n\t\treturn element;\n\t}\n\tif (Array.isArray(element) && element.length === 2) {\n\t\tconst [loop, iteration] = element;\n\t\tif (typeof loop === \"number\" && typeof iteration === \"number\") {\n\t\t\treturn { loop, iteration } as LoopIterationMarker;\n\t\t}\n\t}\n\tthrow new Error(\n\t\t`Invalid path segment tuple element: ${JSON.stringify(element)}`,\n\t);\n}\n\n/**\n * Convert a location to tuple elements.\n */\nfunction locationToTupleElements(location: Location): TupleItem[] {\n\treturn location.map(segmentToTuple);\n}\n\n/**\n * Convert tuple elements back to a location.\n */\nfunction tupleElementsToLocation(elements: TupleItem[]): Location {\n\treturn elements.map(tupleToSegment);\n}\n\n// === Helper Functions ===\n\n/**\n * Convert Buffer to Uint8Array.\n */\nfunction bufferToUint8Array(buf: Buffer): Uint8Array {\n\treturn new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);\n}\n\n/**\n * Convert Uint8Array to Buffer.\n */\nfunction uint8ArrayToBuffer(arr: Uint8Array): Buffer {\n\treturn Buffer.from(arr.buffer, arr.byteOffset, arr.byteLength);\n}\n\n/**\n * Pack tuple items and return as Uint8Array.\n */\nfunction pack(items: TupleItem | TupleItem[]): Uint8Array {\n\tconst buf = tuple.pack(items);\n\treturn bufferToUint8Array(buf);\n}\n\n/**\n * Unpack a Uint8Array and return tuple items.\n */\nfunction unpack(data: Uint8Array): TupleItem[] {\n\tconst buf = uint8ArrayToBuffer(data);\n\treturn tuple.unpack(buf) as TupleItem[];\n}\n\n// === Key Builders ===\n\n/**\n * Build a key for the name registry.\n * Key: [1, index]\n */\nexport function buildNameKey(index: number): Uint8Array {\n\treturn pack([KEY_PREFIX.NAMES, index]);\n}\n\n/**\n * Build a prefix for listing all names.\n * Prefix: [1]\n */\nexport function buildNamePrefix(): Uint8Array {\n\treturn pack([KEY_PREFIX.NAMES]);\n}\n\n/**\n * Build a key for a history entry.\n * Key: [2, ...locationSegments]\n */\nexport function buildHistoryKey(location: Location): Uint8Array {\n\treturn pack([KEY_PREFIX.HISTORY, ...locationToTupleElements(location)]);\n}\n\n/**\n * Build a prefix for listing history entries under a location.\n * Prefix: [2, ...locationSegments]\n */\nexport function buildHistoryPrefix(location: Location): Uint8Array {\n\treturn pack([KEY_PREFIX.HISTORY, ...locationToTupleElements(location)]);\n}\n\n/**\n * Build a key range for loop iteration history entries.\n * Range: [2, ...locationSegments, [loopSegment, fromIteration]] to\n *        [2, ...locationSegments, [loopSegment, toIteration]])\n */\nexport function buildLoopIterationRange(\n\tloopLocation: Location,\n\tloopSegment: number,\n\tfromIteration: number,\n\ttoIteration: number,\n): { start: Uint8Array; end: Uint8Array } {\n\tconst loopLocationSegments = locationToTupleElements(loopLocation);\n\treturn {\n\t\tstart: pack([\n\t\t\tKEY_PREFIX.HISTORY,\n\t\t\t...loopLocationSegments,\n\t\t\t[loopSegment, fromIteration],\n\t\t]),\n\t\tend: pack([\n\t\t\tKEY_PREFIX.HISTORY,\n\t\t\t...loopLocationSegments,\n\t\t\t[loopSegment, toIteration],\n\t\t]),\n\t};\n}\n\n/**\n * Build a prefix for listing all history entries.\n * Prefix: [2]\n */\nexport function buildHistoryPrefixAll(): Uint8Array {\n\treturn pack([KEY_PREFIX.HISTORY]);\n}\n\n/**\n * Build a key for workflow state.\n * Key: [3, 1]\n */\nexport function buildWorkflowStateKey(): Uint8Array {\n\treturn pack([KEY_PREFIX.WORKFLOW, WORKFLOW_FIELD.STATE]);\n}\n\n/**\n * Build a key for workflow output.\n * Key: [3, 2]\n */\nexport function buildWorkflowOutputKey(): Uint8Array {\n\treturn pack([KEY_PREFIX.WORKFLOW, WORKFLOW_FIELD.OUTPUT]);\n}\n\n/**\n * Build a key for workflow error.\n * Key: [3, 3]\n */\nexport function buildWorkflowErrorKey(): Uint8Array {\n\treturn pack([KEY_PREFIX.WORKFLOW, WORKFLOW_FIELD.ERROR]);\n}\n\n/**\n * Build a key for workflow input.\n * Key: [3, 4]\n */\nexport function buildWorkflowInputKey(): Uint8Array {\n\treturn pack([KEY_PREFIX.WORKFLOW, WORKFLOW_FIELD.INPUT]);\n}\n\n/**\n * Build a key for entry metadata.\n * Key: [4, entryId]\n */\nexport function buildEntryMetadataKey(entryId: string): Uint8Array {\n\treturn pack([KEY_PREFIX.ENTRY_METADATA, entryId]);\n}\n\n/**\n * Build a prefix for listing all entry metadata.\n * Prefix: [4]\n */\nexport function buildEntryMetadataPrefix(): Uint8Array {\n\treturn pack([KEY_PREFIX.ENTRY_METADATA]);\n}\n\n// === Key Parsers ===\n\n/**\n * Parse a name key and return the index.\n * Key: [1, index] → index\n */\nexport function parseNameKey(key: Uint8Array): number {\n\tconst elements = unpack(key);\n\tif (elements.length !== 2 || elements[0] !== KEY_PREFIX.NAMES) {\n\t\tthrow new Error(\"Invalid name key\");\n\t}\n\treturn elements[1] as number;\n}\n\n/**\n * Parse a history key and return the location.\n * Key: [2, ...segments] → Location\n */\nexport function parseHistoryKey(key: Uint8Array): Location {\n\tconst elements = unpack(key);\n\tif (elements.length < 1 || elements[0] !== KEY_PREFIX.HISTORY) {\n\t\tthrow new Error(\"Invalid history key\");\n\t}\n\treturn tupleElementsToLocation(elements.slice(1));\n}\n\n/**\n * Parse an entry metadata key and return the entry ID.\n * Key: [4, entryId] → entryId\n */\nexport function parseEntryMetadataKey(key: Uint8Array): string {\n\tconst elements = unpack(key);\n\tif (elements.length !== 2 || elements[0] !== KEY_PREFIX.ENTRY_METADATA) {\n\t\tthrow new Error(\"Invalid entry metadata key\");\n\t}\n\treturn elements[1] as string;\n}\n\n// === Key Comparison Utilities ===\n\n/**\n * Check if a key starts with a prefix.\n */\nexport function keyStartsWith(key: Uint8Array, prefix: Uint8Array): boolean {\n\tif (key.length < prefix.length) {\n\t\treturn false;\n\t}\n\tfor (let i = 0; i < prefix.length; i++) {\n\t\tif (key[i] !== prefix[i]) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n\n/**\n * Compare two keys lexicographically.\n * Returns negative if a < b, 0 if a === b, positive if a > b.\n */\nexport function compareKeys(a: Uint8Array, b: Uint8Array): number {\n\tconst minLen = Math.min(a.length, b.length);\n\tfor (let i = 0; i < minLen; i++) {\n\t\tif (a[i] !== b[i]) {\n\t\t\treturn a[i] - b[i];\n\t\t}\n\t}\n\treturn a.length - b.length;\n}\n\n/**\n * Convert a key to a hex string for debugging.\n */\nexport function keyToHex(key: Uint8Array): string {\n\treturn Array.from(key)\n\t\t.map((b) => b.toString(16).padStart(2, \"0\"))\n\t\t.join(\"\");\n}\n","import type {\n\tLocation,\n\tLoopIterationMarker,\n\tNameIndex,\n\tPathSegment,\n\tStorage,\n} from \"./types.js\";\n\n/**\n * Check if a path segment is a loop iteration marker.\n */\nexport function isLoopIterationMarker(\n\tsegment: PathSegment,\n): segment is LoopIterationMarker {\n\treturn typeof segment === \"object\" && \"loop\" in segment;\n}\n\n/**\n * Register a name in the registry and return its index.\n * If the name already exists, returns the existing index.\n */\nexport function registerName(storage: Storage, name: string): NameIndex {\n\tconst existing = storage.nameRegistry.indexOf(name);\n\tif (existing !== -1) {\n\t\treturn existing;\n\t}\n\tstorage.nameRegistry.push(name);\n\treturn storage.nameRegistry.length - 1;\n}\n\n/**\n * Resolve a name index to its string value.\n */\nexport function resolveName(storage: Storage, index: NameIndex): string {\n\tconst name = storage.nameRegistry[index];\n\tif (name === undefined) {\n\t\tthrow new Error(`Name index ${index} not found in registry`);\n\t}\n\treturn name;\n}\n\n/**\n * Convert a location to a KV key string.\n * Named entries use their string name, loop iterations use ~N format.\n */\nexport function locationToKey(storage: Storage, location: Location): string {\n\treturn location\n\t\t.map((segment) => {\n\t\t\tif (typeof segment === \"number\") {\n\t\t\t\treturn resolveName(storage, segment);\n\t\t\t}\n\t\t\treturn `~${segment.iteration}`;\n\t\t})\n\t\t.join(\"/\");\n}\n\n/**\n * Append a named segment to a location.\n */\nexport function appendName(\n\tstorage: Storage,\n\tlocation: Location,\n\tname: string,\n): Location {\n\tconst nameIndex = registerName(storage, name);\n\treturn [...location, nameIndex];\n}\n\n/**\n * Append a loop iteration segment to a location.\n */\nexport function appendLoopIteration(\n\tstorage: Storage,\n\tlocation: Location,\n\tloopName: string,\n\titeration: number,\n): Location {\n\tconst loopIndex = registerName(storage, loopName);\n\treturn [...location, { loop: loopIndex, iteration }];\n}\n\n/**\n * Create an empty location (root).\n */\nexport function emptyLocation(): Location {\n\treturn [];\n}\n\n/**\n * Get the parent location (all segments except the last).\n */\nexport function parentLocation(location: Location): Location {\n\treturn location.slice(0, -1);\n}\n\n/**\n * Check if one location is a prefix of another.\n */\nexport function isLocationPrefix(\n\tprefix: Location,\n\tlocation: Location,\n): boolean {\n\tif (prefix.length > location.length) {\n\t\treturn false;\n\t}\n\tfor (let i = 0; i < prefix.length; i++) {\n\t\tconst prefixSegment = prefix[i];\n\t\tconst locationSegment = location[i];\n\n\t\tif (\n\t\t\ttypeof prefixSegment === \"number\" &&\n\t\t\ttypeof locationSegment === \"number\"\n\t\t) {\n\t\t\tif (prefixSegment !== locationSegment) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} else if (\n\t\t\tisLoopIterationMarker(prefixSegment) &&\n\t\t\tisLoopIterationMarker(locationSegment)\n\t\t) {\n\t\t\tif (\n\t\t\t\tprefixSegment.loop !== locationSegment.loop ||\n\t\t\t\tprefixSegment.iteration !== locationSegment.iteration\n\t\t\t) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n\n/**\n * Compare two locations for equality.\n */\nexport function locationsEqual(a: Location, b: Location): boolean {\n\tif (a.length !== b.length) {\n\t\treturn false;\n\t}\n\treturn isLocationPrefix(a, b);\n}\n\n/**\n * Get all entry keys that are children of a given location.\n *\n * Note: Returns a map of key → entry for convenience, not key → location.\n * The location can be retrieved from the entry itself via entry.location.\n */\nexport function getChildEntries(\n\tstorage: Storage,\n\tparentLoc: Location,\n): Map<string, Location> {\n\tconst parentKey = locationToKey(storage, parentLoc);\n\tconst children = new Map<string, Location>();\n\n\tfor (const [key, entry] of storage.history.entries) {\n\t\t// Handle empty parent (root) - all entries are children\n\t\tconst isChild =\n\t\t\tparentKey === \"\"\n\t\t\t\t? true\n\t\t\t\t: key.startsWith(`${parentKey}/`) || key === parentKey;\n\n\t\tif (isChild) {\n\t\t\t// Return the actual entry's location, not the parent location\n\t\t\tchildren.set(key, entry.location);\n\t\t}\n\t}\n\n\treturn children;\n}\n","/**\n * Serialization/deserialization utilities for converting between\n * internal TypeScript types and BARE schema types.\n */\n\nimport * as cbor from \"cbor-x\";\nimport type * as v1 from \"../dist/schemas/v1.js\";\nimport {\n\tBranchStatusType as BareBranchStatusType,\n\tEntryStatus as BareEntryStatus,\n\tSleepState as BareSleepState,\n} from \"../dist/schemas/v1.js\";\nimport type {\n\tBranchStatus as InternalBranchStatus,\n\tBranchStatusType as InternalBranchStatusType,\n\tEntry as InternalEntry,\n\tEntryKind as InternalEntryKind,\n\tEntryMetadata as InternalEntryMetadata,\n\tEntryStatus as InternalEntryStatus,\n\tLocation as InternalLocation,\n\tPathSegment as InternalPathSegment,\n\tSleepState as InternalSleepState,\n\tWorkflowState as InternalWorkflowState,\n} from \"../src/types.js\";\nimport {\n\tCURRENT_VERSION,\n\tENTRY_METADATA_VERSIONED,\n\tENTRY_VERSIONED,\n} from \"./versioned.js\";\n\n// === Helper: ArrayBuffer to/from utilities ===\n\nfunction bufferToArrayBuffer(buf: Uint8Array): ArrayBuffer {\n\t// Create a new ArrayBuffer and copy the data to ensure it's not a SharedArrayBuffer\n\tconst arrayBuffer = new ArrayBuffer(buf.byteLength);\n\tnew Uint8Array(arrayBuffer).set(buf);\n\treturn arrayBuffer;\n}\n\nfunction encodeCbor(value: unknown): ArrayBuffer {\n\treturn bufferToArrayBuffer(cbor.encode(value));\n}\n\nfunction decodeCbor<T>(data: ArrayBuffer): T {\n\treturn cbor.decode(new Uint8Array(data)) as T;\n}\n\n/**\n * Validate that a value is a non-null object.\n */\nfunction assertObject(\n\tvalue: unknown,\n\tcontext: string,\n): asserts value is Record<string, unknown> {\n\tif (typeof value !== \"object\" || value === null) {\n\t\tthrow new Error(`${context}: expected object, got ${typeof value}`);\n\t}\n}\n\n/**\n * Validate that a value is a string.\n */\nfunction assertString(\n\tvalue: unknown,\n\tcontext: string,\n): asserts value is string {\n\tif (typeof value !== \"string\") {\n\t\tthrow new Error(`${context}: expected string, got ${typeof value}`);\n\t}\n}\n\n/**\n * Validate that a value is a number.\n */\nfunction _assertNumber(\n\tvalue: unknown,\n\tcontext: string,\n): asserts value is number {\n\tif (typeof value !== \"number\") {\n\t\tthrow new Error(`${context}: expected number, got ${typeof value}`);\n\t}\n}\n\n// === Entry Status Conversion ===\n\nfunction entryStatusToBare(status: InternalEntryStatus): BareEntryStatus {\n\tswitch (status) {\n\t\tcase \"pending\":\n\t\t\treturn BareEntryStatus.PENDING;\n\t\tcase \"running\":\n\t\t\treturn BareEntryStatus.RUNNING;\n\t\tcase \"completed\":\n\t\t\treturn BareEntryStatus.COMPLETED;\n\t\tcase \"failed\":\n\t\t\treturn BareEntryStatus.FAILED;\n\t\tcase \"exhausted\":\n\t\t\treturn BareEntryStatus.EXHAUSTED;\n\t}\n}\n\nfunction entryStatusFromBare(status: BareEntryStatus): InternalEntryStatus {\n\tswitch (status) {\n\t\tcase BareEntryStatus.PENDING:\n\t\t\treturn \"pending\";\n\t\tcase BareEntryStatus.RUNNING:\n\t\t\treturn \"running\";\n\t\tcase BareEntryStatus.COMPLETED:\n\t\t\treturn \"completed\";\n\t\tcase BareEntryStatus.FAILED:\n\t\t\treturn \"failed\";\n\t\tcase BareEntryStatus.EXHAUSTED:\n\t\t\treturn \"exhausted\";\n\t}\n}\n\n// === Sleep State Conversion ===\n\nfunction sleepStateToBare(state: InternalSleepState): BareSleepState {\n\tswitch (state) {\n\t\tcase \"pending\":\n\t\t\treturn BareSleepState.PENDING;\n\t\tcase \"completed\":\n\t\t\treturn BareSleepState.COMPLETED;\n\t\tcase \"interrupted\":\n\t\t\treturn BareSleepState.INTERRUPTED;\n\t}\n}\n\nfunction sleepStateFromBare(state: BareSleepState): InternalSleepState {\n\tswitch (state) {\n\t\tcase BareSleepState.PENDING:\n\t\t\treturn \"pending\";\n\t\tcase BareSleepState.COMPLETED:\n\t\t\treturn \"completed\";\n\t\tcase BareSleepState.INTERRUPTED:\n\t\t\treturn \"interrupted\";\n\t}\n}\n\n// === Branch Status Type Conversion ===\n\nfunction branchStatusTypeToBare(\n\tstatus: InternalBranchStatusType,\n): BareBranchStatusType {\n\tswitch (status) {\n\t\tcase \"pending\":\n\t\t\treturn BareBranchStatusType.PENDING;\n\t\tcase \"running\":\n\t\t\treturn BareBranchStatusType.RUNNING;\n\t\tcase \"completed\":\n\t\t\treturn BareBranchStatusType.COMPLETED;\n\t\tcase \"failed\":\n\t\t\treturn BareBranchStatusType.FAILED;\n\t\tcase \"cancelled\":\n\t\t\treturn BareBranchStatusType.CANCELLED;\n\t}\n}\n\nfunction branchStatusTypeFromBare(\n\tstatus: BareBranchStatusType,\n): InternalBranchStatusType {\n\tswitch (status) {\n\t\tcase BareBranchStatusType.PENDING:\n\t\t\treturn \"pending\";\n\t\tcase BareBranchStatusType.RUNNING:\n\t\t\treturn \"running\";\n\t\tcase BareBranchStatusType.COMPLETED:\n\t\t\treturn \"completed\";\n\t\tcase BareBranchStatusType.FAILED:\n\t\t\treturn \"failed\";\n\t\tcase BareBranchStatusType.CANCELLED:\n\t\t\treturn \"cancelled\";\n\t}\n}\n\n// === Location Conversion ===\n\nfunction locationToBare(location: InternalLocation): v1.Location {\n\treturn location.map((segment): v1.PathSegment => {\n\t\tif (typeof segment === \"number\") {\n\t\t\treturn { tag: \"NameIndex\", val: segment };\n\t\t}\n\t\treturn {\n\t\t\ttag: \"LoopIterationMarker\",\n\t\t\tval: {\n\t\t\t\tloop: segment.loop,\n\t\t\t\titeration: segment.iteration,\n\t\t\t},\n\t\t};\n\t});\n}\n\nfunction locationFromBare(location: v1.Location): InternalLocation {\n\treturn location.map((segment): InternalPathSegment => {\n\t\tif (segment.tag === \"NameIndex\") {\n\t\t\treturn segment.val;\n\t\t}\n\t\treturn {\n\t\t\tloop: segment.val.loop,\n\t\t\titeration: segment.val.iteration,\n\t\t};\n\t});\n}\n\n// === Branch Status Conversion ===\n\nfunction branchStatusToBare(status: InternalBranchStatus): v1.BranchStatus {\n\treturn {\n\t\tstatus: branchStatusTypeToBare(status.status),\n\t\toutput: status.output !== undefined ? encodeCbor(status.output) : null,\n\t\terror: status.error ?? null,\n\t};\n}\n\nfunction branchStatusFromBare(status: v1.BranchStatus): InternalBranchStatus {\n\treturn {\n\t\tstatus: branchStatusTypeFromBare(status.status),\n\t\toutput: status.output !== null ? decodeCbor(status.output) : undefined,\n\t\terror: status.error ?? undefined,\n\t};\n}\n\n// === Entry Kind Conversion ===\n\nfunction entryKindToBare(kind: InternalEntryKind): v1.EntryKind {\n\tswitch (kind.type) {\n\t\tcase \"step\":\n\t\t\treturn {\n\t\t\t\ttag: \"StepEntry\",\n\t\t\t\tval: {\n\t\t\t\t\toutput:\n\t\t\t\t\t\tkind.data.output !== undefined\n\t\t\t\t\t\t\t? encodeCbor(kind.data.output)\n\t\t\t\t\t\t\t: null,\n\t\t\t\t\terror: kind.data.error ?? null,\n\t\t\t\t},\n\t\t\t};\n\t\tcase \"loop\":\n\t\t\treturn {\n\t\t\t\ttag: \"LoopEntry\",\n\t\t\t\tval: {\n\t\t\t\t\tstate: encodeCbor(kind.data.state),\n\t\t\t\t\titeration: kind.data.iteration,\n\t\t\t\t\toutput:\n\t\t\t\t\t\tkind.data.output !== undefined\n\t\t\t\t\t\t\t? encodeCbor(kind.data.output)\n\t\t\t\t\t\t\t: null,\n\t\t\t\t},\n\t\t\t};\n\t\tcase \"sleep\":\n\t\t\treturn {\n\t\t\t\ttag: \"SleepEntry\",\n\t\t\t\tval: {\n\t\t\t\t\tdeadline: BigInt(kind.data.deadline),\n\t\t\t\t\tstate: sleepStateToBare(kind.data.state),\n\t\t\t\t},\n\t\t\t};\n\t\tcase \"message\":\n\t\t\treturn {\n\t\t\t\ttag: \"MessageEntry\",\n\t\t\t\tval: {\n\t\t\t\t\tname: kind.data.name,\n\t\t\t\t\tmessageData: encodeCbor(kind.data.data),\n\t\t\t\t},\n\t\t\t};\n\t\tcase \"rollback_checkpoint\":\n\t\t\treturn {\n\t\t\t\ttag: \"RollbackCheckpointEntry\",\n\t\t\t\tval: {\n\t\t\t\t\tname: kind.data.name,\n\t\t\t\t},\n\t\t\t};\n\t\tcase \"join\":\n\t\t\treturn {\n\t\t\t\ttag: \"JoinEntry\",\n\t\t\t\tval: {\n\t\t\t\t\tbranches: new Map(\n\t\t\t\t\t\tObject.entries(kind.data.branches).map(\n\t\t\t\t\t\t\t([name, status]) => [\n\t\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\t\tbranchStatusToBare(status),\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t},\n\t\t\t};\n\t\tcase \"race\":\n\t\t\treturn {\n\t\t\t\ttag: \"RaceEntry\",\n\t\t\t\tval: {\n\t\t\t\t\twinner: kind.data.winner,\n\t\t\t\t\tbranches: new Map(\n\t\t\t\t\t\tObject.entries(kind.data.branches).map(\n\t\t\t\t\t\t\t([name, status]) => [\n\t\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\t\tbranchStatusToBare(status),\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t},\n\t\t\t};\n\t\tcase \"removed\":\n\t\t\treturn {\n\t\t\t\ttag: \"RemovedEntry\",\n\t\t\t\tval: {\n\t\t\t\t\toriginalType: kind.data.originalType,\n\t\t\t\t\toriginalName: kind.data.originalName ?? null,\n\t\t\t\t},\n\t\t\t};\n\t\tcase \"version_check\":\n\t\t\treturn {\n\t\t\t\ttag: \"VersionCheckEntry\",\n\t\t\t\tval: {\n\t\t\t\t\tresolved: kind.data.resolved,\n\t\t\t\t\tlatest: kind.data.latest,\n\t\t\t\t},\n\t\t\t};\n\t}\n}\n\nfunction entryKindFromBare(kind: v1.EntryKind): InternalEntryKind {\n\tswitch (kind.tag) {\n\t\tcase \"StepEntry\":\n\t\t\treturn {\n\t\t\t\ttype: \"step\",\n\t\t\t\tdata: {\n\t\t\t\t\toutput:\n\t\t\t\t\t\tkind.val.output !== null\n\t\t\t\t\t\t\t? decodeCbor(kind.val.output)\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\terror: kind.val.error ?? undefined,\n\t\t\t\t},\n\t\t\t};\n\t\tcase \"LoopEntry\":\n\t\t\treturn {\n\t\t\t\ttype: \"loop\",\n\t\t\t\tdata: {\n\t\t\t\t\tstate: decodeCbor(kind.val.state),\n\t\t\t\t\titeration: kind.val.iteration,\n\t\t\t\t\toutput:\n\t\t\t\t\t\tkind.val.output !== null\n\t\t\t\t\t\t\t? decodeCbor(kind.val.output)\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t},\n\t\t\t};\n\t\tcase \"SleepEntry\":\n\t\t\treturn {\n\t\t\t\ttype: \"sleep\",\n\t\t\t\tdata: {\n\t\t\t\t\tdeadline: Number(kind.val.deadline),\n\t\t\t\t\tstate: sleepStateFromBare(kind.val.state),\n\t\t\t\t},\n\t\t\t};\n\t\tcase \"MessageEntry\":\n\t\t\treturn {\n\t\t\t\ttype: \"message\",\n\t\t\t\tdata: {\n\t\t\t\t\tname: kind.val.name,\n\t\t\t\t\tdata: decodeCbor(kind.val.messageData),\n\t\t\t\t},\n\t\t\t};\n\t\tcase \"RollbackCheckpointEntry\":\n\t\t\treturn {\n\t\t\t\ttype: \"rollback_checkpoint\",\n\t\t\t\tdata: {\n\t\t\t\t\tname: kind.val.name,\n\t\t\t\t},\n\t\t\t};\n\t\tcase \"JoinEntry\":\n\t\t\treturn {\n\t\t\t\ttype: \"join\",\n\t\t\t\tdata: {\n\t\t\t\t\tbranches: Object.fromEntries(\n\t\t\t\t\t\tArray.from(kind.val.branches.entries()).map(\n\t\t\t\t\t\t\t([name, status]) => [\n\t\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\t\tbranchStatusFromBare(status),\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t},\n\t\t\t};\n\t\tcase \"RaceEntry\":\n\t\t\treturn {\n\t\t\t\ttype: \"race\",\n\t\t\t\tdata: {\n\t\t\t\t\twinner: kind.val.winner,\n\t\t\t\t\tbranches: Object.fromEntries(\n\t\t\t\t\t\tArray.from(kind.val.branches.entries()).map(\n\t\t\t\t\t\t\t([name, status]) => [\n\t\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\t\tbranchStatusFromBare(status),\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t},\n\t\t\t};\n\t\tcase \"RemovedEntry\":\n\t\t\treturn {\n\t\t\t\ttype: \"removed\",\n\t\t\t\tdata: {\n\t\t\t\t\toriginalType: kind.val\n\t\t\t\t\t\t.originalType as InternalEntryKind[\"type\"],\n\t\t\t\t\toriginalName: kind.val.originalName ?? undefined,\n\t\t\t\t},\n\t\t\t};\n\t\tcase \"VersionCheckEntry\":\n\t\t\treturn {\n\t\t\t\ttype: \"version_check\",\n\t\t\t\tdata: {\n\t\t\t\t\tresolved: kind.val.resolved,\n\t\t\t\t\tlatest: kind.val.latest,\n\t\t\t\t},\n\t\t\t};\n\t\tdefault:\n\t\t\tthrow new Error(\n\t\t\t\t`Unknown entry kind: ${(kind as { tag: string }).tag}`,\n\t\t\t);\n\t}\n}\n\n// === Entry Conversion & Serialization ===\n\nfunction entryToBare(entry: InternalEntry): v1.Entry {\n\treturn {\n\t\tid: entry.id,\n\t\tlocation: locationToBare(entry.location),\n\t\tkind: entryKindToBare(entry.kind),\n\t};\n}\n\nfunction entryFromBare(bareEntry: v1.Entry): InternalEntry {\n\treturn {\n\t\tid: bareEntry.id,\n\t\tlocation: locationFromBare(bareEntry.location),\n\t\tkind: entryKindFromBare(bareEntry.kind),\n\t\tdirty: false,\n\t};\n}\n\nexport function serializeEntry(entry: InternalEntry): Uint8Array {\n\tconst bareEntry = entryToBare(entry);\n\treturn ENTRY_VERSIONED.serializeWithEmbeddedVersion(\n\t\tbareEntry,\n\t\tCURRENT_VERSION,\n\t);\n}\n\nexport function deserializeEntry(bytes: Uint8Array): InternalEntry {\n\tconst bareEntry = ENTRY_VERSIONED.deserializeWithEmbeddedVersion(bytes);\n\treturn entryFromBare(bareEntry);\n}\n\n// === Entry Metadata Conversion & Serialization ===\n\nfunction entryMetadataToBare(\n\tmetadata: InternalEntryMetadata,\n): v1.EntryMetadata {\n\treturn {\n\t\tstatus: entryStatusToBare(metadata.status),\n\t\terror: metadata.error ?? null,\n\t\tattempts: metadata.attempts,\n\t\tlastAttemptAt: BigInt(metadata.lastAttemptAt),\n\t\tcreatedAt: BigInt(metadata.createdAt),\n\t\tcompletedAt:\n\t\t\tmetadata.completedAt !== undefined\n\t\t\t\t? BigInt(metadata.completedAt)\n\t\t\t\t: null,\n\t\trollbackCompletedAt:\n\t\t\tmetadata.rollbackCompletedAt !== undefined\n\t\t\t\t? BigInt(metadata.rollbackCompletedAt)\n\t\t\t\t: null,\n\t\trollbackError: metadata.rollbackError ?? null,\n\t};\n}\n\nfunction entryMetadataFromBare(\n\tbareMetadata: v1.EntryMetadata,\n): InternalEntryMetadata {\n\treturn {\n\t\tstatus: entryStatusFromBare(bareMetadata.status),\n\t\terror: bareMetadata.error ?? undefined,\n\t\tattempts: bareMetadata.attempts,\n\t\tlastAttemptAt: Number(bareMetadata.lastAttemptAt),\n\t\tcreatedAt: Number(bareMetadata.createdAt),\n\t\tcompletedAt:\n\t\t\tbareMetadata.completedAt !== null\n\t\t\t\t? Number(bareMetadata.completedAt)\n\t\t\t\t: undefined,\n\t\trollbackCompletedAt:\n\t\t\tbareMetadata.rollbackCompletedAt !== null\n\t\t\t\t? Number(bareMetadata.rollbackCompletedAt)\n\t\t\t\t: undefined,\n\t\trollbackError: bareMetadata.rollbackError ?? undefined,\n\t\tdirty: false,\n\t};\n}\n\nexport function serializeEntryMetadata(\n\tmetadata: InternalEntryMetadata,\n): Uint8Array {\n\tconst bareMetadata = entryMetadataToBare(metadata);\n\treturn ENTRY_METADATA_VERSIONED.serializeWithEmbeddedVersion(\n\t\tbareMetadata,\n\t\tCURRENT_VERSION,\n\t);\n}\n\nexport function deserializeEntryMetadata(\n\tbytes: Uint8Array,\n): InternalEntryMetadata {\n\tconst bareMetadata =\n\t\tENTRY_METADATA_VERSIONED.deserializeWithEmbeddedVersion(bytes);\n\treturn entryMetadataFromBare(bareMetadata);\n}\n\n// === Workflow Metadata Serialization ===\n// Note: These are used for reading/writing individual workflow fields\n\nexport function serializeWorkflowState(\n\tstate: InternalWorkflowState,\n): Uint8Array {\n\t// For simple values, we can encode them directly without the full metadata struct\n\t// Using a single byte for efficiency\n\tconst encoder = new TextEncoder();\n\treturn encoder.encode(state);\n}\n\nexport function deserializeWorkflowState(\n\tbytes: Uint8Array,\n): InternalWorkflowState {\n\tconst decoder = new TextDecoder();\n\tconst state = decoder.decode(bytes) as InternalWorkflowState;\n\tconst validStates: InternalWorkflowState[] = [\n\t\t\"pending\",\n\t\t\"running\",\n\t\t\"sleeping\",\n\t\t\"failed\",\n\t\t\"completed\",\n\t\t\"cancelled\",\n\t\t\"rolling_back\",\n\t];\n\tif (!validStates.includes(state)) {\n\t\tthrow new Error(`Invalid workflow state: ${state}`);\n\t}\n\treturn state;\n}\n\nexport function serializeWorkflowOutput(output: unknown): Uint8Array {\n\treturn cbor.encode(output);\n}\n\nexport function deserializeWorkflowOutput<T>(bytes: Uint8Array): T {\n\ttry {\n\t\treturn cbor.decode(bytes) as T;\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Failed to deserialize workflow output: ${error instanceof Error ? error.message : String(error)}`,\n\t\t);\n\t}\n}\n\n/**\n * Structured error type for serialization.\n */\ninterface SerializedWorkflowError {\n\tname: string;\n\tmessage: string;\n\tstack?: string;\n\tmetadata?: Record<string, unknown>;\n}\n\nexport function serializeWorkflowError(\n\terror: SerializedWorkflowError,\n): Uint8Array {\n\treturn cbor.encode(error);\n}\n\nexport function deserializeWorkflowError(\n\tbytes: Uint8Array,\n): SerializedWorkflowError {\n\tconst decoded = cbor.decode(bytes);\n\tassertObject(decoded, \"WorkflowError\");\n\t// Validate required fields\n\tconst obj = decoded as Record<string, unknown>;\n\tassertString(obj.name, \"WorkflowError.name\");\n\tassertString(obj.message, \"WorkflowError.message\");\n\treturn {\n\t\tname: obj.name,\n\t\tmessage: obj.message,\n\t\tstack: typeof obj.stack === \"string\" ? obj.stack : undefined,\n\t\tmetadata:\n\t\t\ttypeof obj.metadata === \"object\" && obj.metadata !== null\n\t\t\t\t? (obj.metadata as Record<string, unknown>)\n\t\t\t\t: undefined,\n\t};\n}\n\nexport function serializeWorkflowInput(input: unknown): Uint8Array {\n\treturn cbor.encode(input);\n}\n\nexport function deserializeWorkflowInput<T>(bytes: Uint8Array): T {\n\ttry {\n\t\treturn cbor.decode(bytes) as T;\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Failed to deserialize workflow input: ${error instanceof Error ? error.message : String(error)}`,\n\t\t);\n\t}\n}\n\n// === Name Registry Serialization ===\n\nexport function serializeName(name: string): Uint8Array {\n\tconst encoder = new TextEncoder();\n\treturn encoder.encode(name);\n}\n\nexport function deserializeName(bytes: Uint8Array): string {\n\tconst decoder = new TextDecoder();\n\treturn decoder.decode(bytes);\n}\n","// @generated - post-processed by compile-bare.ts\nimport * as bare from \"@rivetkit/bare-ts\"\n\nconst config = /* @__PURE__ */ bare.Config({})\n\nexport type u32 = number\nexport type u64 = bigint\n\nexport type Cbor = ArrayBuffer\n\nexport function readCbor(bc: bare.ByteCursor): Cbor {\n    return bare.readData(bc)\n}\n\nexport function writeCbor(bc: bare.ByteCursor, x: Cbor): void {\n    bare.writeData(bc, x)\n}\n\nexport type NameIndex = u32\n\nexport function readNameIndex(bc: bare.ByteCursor): NameIndex {\n    return bare.readU32(bc)\n}\n\nexport function writeNameIndex(bc: bare.ByteCursor, x: NameIndex): void {\n    bare.writeU32(bc, x)\n}\n\nexport type LoopIterationMarker = {\n    readonly loop: NameIndex,\n    readonly iteration: u32,\n}\n\nexport function readLoopIterationMarker(bc: bare.ByteCursor): LoopIterationMarker {\n    return {\n        loop: readNameIndex(bc),\n        iteration: bare.readU32(bc),\n    }\n}\n\nexport function writeLoopIterationMarker(bc: bare.ByteCursor, x: LoopIterationMarker): void {\n    writeNameIndex(bc, x.loop)\n    bare.writeU32(bc, x.iteration)\n}\n\nexport type PathSegment =\n    | { readonly tag: \"NameIndex\", readonly val: NameIndex }\n    | { readonly tag: \"LoopIterationMarker\", readonly val: LoopIterationMarker }\n\nexport function readPathSegment(bc: bare.ByteCursor): PathSegment {\n    const offset = bc.offset\n    const tag = bare.readU8(bc)\n    switch (tag) {\n        case 0:\n            return { tag: \"NameIndex\", val: readNameIndex(bc) }\n        case 1:\n            return { tag: \"LoopIterationMarker\", val: readLoopIterationMarker(bc) }\n        default: {\n            bc.offset = offset\n            throw new bare.BareError(offset, \"invalid tag\")\n        }\n    }\n}\n\nexport function writePathSegment(bc: bare.ByteCursor, x: PathSegment): void {\n    switch (x.tag) {\n        case \"NameIndex\": {\n            bare.writeU8(bc, 0)\n            writeNameIndex(bc, x.val)\n            break\n        }\n        case \"LoopIterationMarker\": {\n            bare.writeU8(bc, 1)\n            writeLoopIterationMarker(bc, x.val)\n            break\n        }\n    }\n}\n\nexport type Location = readonly PathSegment[]\n\nexport function readLocation(bc: bare.ByteCursor): Location {\n    const len = bare.readUintSafe(bc)\n    if (len === 0) { return [] }\n    const result = [readPathSegment(bc)]\n    for (let i = 1; i < len; i++) {\n        result[i] = readPathSegment(bc)\n    }\n    return result\n}\n\nexport function writeLocation(bc: bare.ByteCursor, x: Location): void {\n    bare.writeUintSafe(bc, x.length)\n    for (let i = 0; i < x.length; i++) {\n        writePathSegment(bc, x[i])\n    }\n}\n\nexport enum EntryStatus {\n    PENDING = \"PENDING\",\n    RUNNING = \"RUNNING\",\n    COMPLETED = \"COMPLETED\",\n    FAILED = \"FAILED\",\n    EXHAUSTED = \"EXHAUSTED\",\n}\n\nexport function readEntryStatus(bc: bare.ByteCursor): EntryStatus {\n    const offset = bc.offset\n    const tag = bare.readU8(bc)\n    switch (tag) {\n        case 0:\n            return EntryStatus.PENDING\n        case 1:\n            return EntryStatus.RUNNING\n        case 2:\n            return EntryStatus.COMPLETED\n        case 3:\n            return EntryStatus.FAILED\n        case 4:\n            return EntryStatus.EXHAUSTED\n        default: {\n            bc.offset = offset\n            throw new bare.BareError(offset, \"invalid tag\")\n        }\n    }\n}\n\nexport function writeEntryStatus(bc: bare.ByteCursor, x: EntryStatus): void {\n    switch (x) {\n        case EntryStatus.PENDING: {\n            bare.writeU8(bc, 0)\n            break\n        }\n        case EntryStatus.RUNNING: {\n            bare.writeU8(bc, 1)\n            break\n        }\n        case EntryStatus.COMPLETED: {\n            bare.writeU8(bc, 2)\n            break\n        }\n        case EntryStatus.FAILED: {\n            bare.writeU8(bc, 3)\n            break\n        }\n        case EntryStatus.EXHAUSTED: {\n            bare.writeU8(bc, 4)\n            break\n        }\n    }\n}\n\nexport enum SleepState {\n    PENDING = \"PENDING\",\n    COMPLETED = \"COMPLETED\",\n    INTERRUPTED = \"INTERRUPTED\",\n}\n\nexport function readSleepState(bc: bare.ByteCursor): SleepState {\n    const offset = bc.offset\n    const tag = bare.readU8(bc)\n    switch (tag) {\n        case 0:\n            return SleepState.PENDING\n        case 1:\n            return SleepState.COMPLETED\n        case 2:\n            return SleepState.INTERRUPTED\n        default: {\n            bc.offset = offset\n            throw new bare.BareError(offset, \"invalid tag\")\n        }\n    }\n}\n\nexport function writeSleepState(bc: bare.ByteCursor, x: SleepState): void {\n    switch (x) {\n        case SleepState.PENDING: {\n            bare.writeU8(bc, 0)\n            break\n        }\n        case SleepState.COMPLETED: {\n            bare.writeU8(bc, 1)\n            break\n        }\n        case SleepState.INTERRUPTED: {\n            bare.writeU8(bc, 2)\n            break\n        }\n    }\n}\n\nexport enum BranchStatusType {\n    PENDING = \"PENDING\",\n    RUNNING = \"RUNNING\",\n    COMPLETED = \"COMPLETED\",\n    FAILED = \"FAILED\",\n    CANCELLED = \"CANCELLED\",\n}\n\nexport function readBranchStatusType(bc: bare.ByteCursor): BranchStatusType {\n    const offset = bc.offset\n    const tag = bare.readU8(bc)\n    switch (tag) {\n        case 0:\n            return BranchStatusType.PENDING\n        case 1:\n            return BranchStatusType.RUNNING\n        case 2:\n            return BranchStatusType.COMPLETED\n        case 3:\n            return BranchStatusType.FAILED\n        case 4:\n            return BranchStatusType.CANCELLED\n        default: {\n            bc.offset = offset\n            throw new bare.BareError(offset, \"invalid tag\")\n        }\n    }\n}\n\nexport function writeBranchStatusType(bc: bare.ByteCursor, x: BranchStatusType): void {\n    switch (x) {\n        case BranchStatusType.PENDING: {\n            bare.writeU8(bc, 0)\n            break\n        }\n        case BranchStatusType.RUNNING: {\n            bare.writeU8(bc, 1)\n            break\n        }\n        case BranchStatusType.COMPLETED: {\n            bare.writeU8(bc, 2)\n            break\n        }\n        case BranchStatusType.FAILED: {\n            bare.writeU8(bc, 3)\n            break\n        }\n        case BranchStatusType.CANCELLED: {\n            bare.writeU8(bc, 4)\n            break\n        }\n    }\n}\n\nfunction read0(bc: bare.ByteCursor): Cbor | null {\n    return bare.readBool(bc)\n        ? readCbor(bc)\n        : null\n}\n\nfunction write0(bc: bare.ByteCursor, x: Cbor | null): void {\n    bare.writeBool(bc, x !== null)\n    if (x !== null) {\n        writeCbor(bc, x)\n    }\n}\n\nfunction read1(bc: bare.ByteCursor): string | null {\n    return bare.readBool(bc)\n        ? bare.readString(bc)\n        : null\n}\n\nfunction write1(bc: bare.ByteCursor, x: string | null): void {\n    bare.writeBool(bc, x !== null)\n    if (x !== null) {\n        bare.writeString(bc, x)\n    }\n}\n\nexport type StepEntry = {\n    readonly output: Cbor | null,\n    readonly error: string | null,\n}\n\nexport function readStepEntry(bc: bare.ByteCursor): StepEntry {\n    return {\n        output: read0(bc),\n        error: read1(bc),\n    }\n}\n\nexport function writeStepEntry(bc: bare.ByteCursor, x: StepEntry): void {\n    write0(bc, x.output)\n    write1(bc, x.error)\n}\n\nexport type LoopEntry = {\n    readonly state: Cbor,\n    readonly iteration: u32,\n    readonly output: Cbor | null,\n}\n\nexport function readLoopEntry(bc: bare.ByteCursor): LoopEntry {\n    return {\n        state: readCbor(bc),\n        iteration: bare.readU32(bc),\n        output: read0(bc),\n    }\n}\n\nexport function writeLoopEntry(bc: bare.ByteCursor, x: LoopEntry): void {\n    writeCbor(bc, x.state)\n    bare.writeU32(bc, x.iteration)\n    write0(bc, x.output)\n}\n\nexport type SleepEntry = {\n    readonly deadline: u64,\n    readonly state: SleepState,\n}\n\nexport function readSleepEntry(bc: bare.ByteCursor): SleepEntry {\n    return {\n        deadline: bare.readU64(bc),\n        state: readSleepState(bc),\n    }\n}\n\nexport function writeSleepEntry(bc: bare.ByteCursor, x: SleepEntry): void {\n    bare.writeU64(bc, x.deadline)\n    writeSleepState(bc, x.state)\n}\n\nexport type MessageEntry = {\n    readonly name: string,\n    readonly messageData: Cbor,\n}\n\nexport function readMessageEntry(bc: bare.ByteCursor): MessageEntry {\n    return {\n        name: bare.readString(bc),\n        messageData: readCbor(bc),\n    }\n}\n\nexport function writeMessageEntry(bc: bare.ByteCursor, x: MessageEntry): void {\n    bare.writeString(bc, x.name)\n    writeCbor(bc, x.messageData)\n}\n\nexport type RollbackCheckpointEntry = {\n    readonly name: string,\n}\n\nexport function readRollbackCheckpointEntry(bc: bare.ByteCursor): RollbackCheckpointEntry {\n    return {\n        name: bare.readString(bc),\n    }\n}\n\nexport function writeRollbackCheckpointEntry(bc: bare.ByteCursor, x: RollbackCheckpointEntry): void {\n    bare.writeString(bc, x.name)\n}\n\nexport type BranchStatus = {\n    readonly status: BranchStatusType,\n    readonly output: Cbor | null,\n    readonly error: string | null,\n}\n\nexport function readBranchStatus(bc: bare.ByteCursor): BranchStatus {\n    return {\n        status: readBranchStatusType(bc),\n        output: read0(bc),\n        error: read1(bc),\n    }\n}\n\nexport function writeBranchStatus(bc: bare.ByteCursor, x: BranchStatus): void {\n    writeBranchStatusType(bc, x.status)\n    write0(bc, x.output)\n    write1(bc, x.error)\n}\n\nfunction read2(bc: bare.ByteCursor): ReadonlyMap<string, BranchStatus> {\n    const len = bare.readUintSafe(bc)\n    const result = new Map<string, BranchStatus>()\n    for (let i = 0; i < len; i++) {\n        const offset = bc.offset\n        const key = bare.readString(bc)\n        if (result.has(key)) {\n            bc.offset = offset\n            throw new bare.BareError(offset, \"duplicated key\")\n        }\n        result.set(key, readBranchStatus(bc))\n    }\n    return result\n}\n\nfunction write2(bc: bare.ByteCursor, x: ReadonlyMap<string, BranchStatus>): void {\n    bare.writeUintSafe(bc, x.size)\n    for(const kv of x) {\n        bare.writeString(bc, kv[0])\n        writeBranchStatus(bc, kv[1])\n    }\n}\n\nexport type JoinEntry = {\n    readonly branches: ReadonlyMap<string, BranchStatus>,\n}\n\nexport function readJoinEntry(bc: bare.ByteCursor): JoinEntry {\n    return {\n        branches: read2(bc),\n    }\n}\n\nexport function writeJoinEntry(bc: bare.ByteCursor, x: JoinEntry): void {\n    write2(bc, x.branches)\n}\n\nexport type RaceEntry = {\n    readonly winner: string | null,\n    readonly branches: ReadonlyMap<string, BranchStatus>,\n}\n\nexport function readRaceEntry(bc: bare.ByteCursor): RaceEntry {\n    return {\n        winner: read1(bc),\n        branches: read2(bc),\n    }\n}\n\nexport function writeRaceEntry(bc: bare.ByteCursor, x: RaceEntry): void {\n    write1(bc, x.winner)\n    write2(bc, x.branches)\n}\n\nexport type RemovedEntry = {\n    readonly originalType: string,\n    readonly originalName: string | null,\n}\n\nexport function readRemovedEntry(bc: bare.ByteCursor): RemovedEntry {\n    return {\n        originalType: bare.readString(bc),\n        originalName: read1(bc),\n    }\n}\n\nexport function writeRemovedEntry(bc: bare.ByteCursor, x: RemovedEntry): void {\n    bare.writeString(bc, x.originalType)\n    write1(bc, x.originalName)\n}\n\nexport type VersionCheckEntry = {\n    readonly resolved: u32,\n    readonly latest: u32,\n}\n\nexport function readVersionCheckEntry(bc: bare.ByteCursor): VersionCheckEntry {\n    return {\n        resolved: bare.readU32(bc),\n        latest: bare.readU32(bc),\n    }\n}\n\nexport function writeVersionCheckEntry(bc: bare.ByteCursor, x: VersionCheckEntry): void {\n    bare.writeU32(bc, x.resolved)\n    bare.writeU32(bc, x.latest)\n}\n\nexport type EntryKind =\n    | { readonly tag: \"StepEntry\", readonly val: StepEntry }\n    | { readonly tag: \"LoopEntry\", readonly val: LoopEntry }\n    | { readonly tag: \"SleepEntry\", readonly val: SleepEntry }\n    | { readonly tag: \"MessageEntry\", readonly val: MessageEntry }\n    | { readonly tag: \"RollbackCheckpointEntry\", readonly val: RollbackCheckpointEntry }\n    | { readonly tag: \"JoinEntry\", readonly val: JoinEntry }\n    | { readonly tag: \"RaceEntry\", readonly val: RaceEntry }\n    | { readonly tag: \"RemovedEntry\", readonly val: RemovedEntry }\n    | { readonly tag: \"VersionCheckEntry\", readonly val: VersionCheckEntry }\n\nexport function readEntryKind(bc: bare.ByteCursor): EntryKind {\n    const offset = bc.offset\n    const tag = bare.readU8(bc)\n    switch (tag) {\n        case 0:\n            return { tag: \"StepEntry\", val: readStepEntry(bc) }\n        case 1:\n            return { tag: \"LoopEntry\", val: readLoopEntry(bc) }\n        case 2:\n            return { tag: \"SleepEntry\", val: readSleepEntry(bc) }\n        case 3:\n            return { tag: \"MessageEntry\", val: readMessageEntry(bc) }\n        case 4:\n            return { tag: \"RollbackCheckpointEntry\", val: readRollbackCheckpointEntry(bc) }\n        case 5:\n            return { tag: \"JoinEntry\", val: readJoinEntry(bc) }\n        case 6:\n            return { tag: \"RaceEntry\", val: readRaceEntry(bc) }\n        case 7:\n            return { tag: \"RemovedEntry\", val: readRemovedEntry(bc) }\n        case 8:\n            return { tag: \"VersionCheckEntry\", val: readVersionCheckEntry(bc) }\n        default: {\n            bc.offset = offset\n            throw new bare.BareError(offset, \"invalid tag\")\n        }\n    }\n}\n\nexport function writeEntryKind(bc: bare.ByteCursor, x: EntryKind): void {\n    switch (x.tag) {\n        case \"StepEntry\": {\n            bare.writeU8(bc, 0)\n            writeStepEntry(bc, x.val)\n            break\n        }\n        case \"LoopEntry\": {\n            bare.writeU8(bc, 1)\n            writeLoopEntry(bc, x.val)\n            break\n        }\n        case \"SleepEntry\": {\n            bare.writeU8(bc, 2)\n            writeSleepEntry(bc, x.val)\n            break\n        }\n        case \"MessageEntry\": {\n            bare.writeU8(bc, 3)\n            writeMessageEntry(bc, x.val)\n            break\n        }\n        case \"RollbackCheckpointEntry\": {\n            bare.writeU8(bc, 4)\n            writeRollbackCheckpointEntry(bc, x.val)\n            break\n        }\n        case \"JoinEntry\": {\n            bare.writeU8(bc, 5)\n            writeJoinEntry(bc, x.val)\n            break\n        }\n        case \"RaceEntry\": {\n            bare.writeU8(bc, 6)\n            writeRaceEntry(bc, x.val)\n            break\n        }\n        case \"RemovedEntry\": {\n            bare.writeU8(bc, 7)\n            writeRemovedEntry(bc, x.val)\n            break\n        }\n        case \"VersionCheckEntry\": {\n            bare.writeU8(bc, 8)\n            writeVersionCheckEntry(bc, x.val)\n            break\n        }\n    }\n}\n\nexport type Entry = {\n    readonly id: string,\n    readonly location: Location,\n    readonly kind: EntryKind,\n}\n\nexport function readEntry(bc: bare.ByteCursor): Entry {\n    return {\n        id: bare.readString(bc),\n        location: readLocation(bc),\n        kind: readEntryKind(bc),\n    }\n}\n\nexport function writeEntry(bc: bare.ByteCursor, x: Entry): void {\n    bare.writeString(bc, x.id)\n    writeLocation(bc, x.location)\n    writeEntryKind(bc, x.kind)\n}\n\nexport function encodeEntry(x: Entry): Uint8Array {\n    const bc = new bare.ByteCursor(\n        new Uint8Array(config.initialBufferLength),\n        config\n    )\n    writeEntry(bc, x)\n    return new Uint8Array(bc.view.buffer, bc.view.byteOffset, bc.offset)\n}\n\nexport function decodeEntry(bytes: Uint8Array): Entry {\n    const bc = new bare.ByteCursor(bytes, config)\n    const result = readEntry(bc)\n    if (bc.offset < bc.view.byteLength) {\n        throw new bare.BareError(bc.offset, \"remaining bytes\")\n    }\n    return result\n}\n\nfunction read3(bc: bare.ByteCursor): u64 | null {\n    return bare.readBool(bc)\n        ? bare.readU64(bc)\n        : null\n}\n\nfunction write3(bc: bare.ByteCursor, x: u64 | null): void {\n    bare.writeBool(bc, x !== null)\n    if (x !== null) {\n        bare.writeU64(bc, x)\n    }\n}\n\nexport type EntryMetadata = {\n    readonly status: EntryStatus,\n    readonly error: string | null,\n    readonly attempts: u32,\n    readonly lastAttemptAt: u64,\n    readonly createdAt: u64,\n    readonly completedAt: u64 | null,\n    readonly rollbackCompletedAt: u64 | null,\n    readonly rollbackError: string | null,\n}\n\nexport function readEntryMetadata(bc: bare.ByteCursor): EntryMetadata {\n    return {\n        status: readEntryStatus(bc),\n        error: read1(bc),\n        attempts: bare.readU32(bc),\n        lastAttemptAt: bare.readU64(bc),\n        createdAt: bare.readU64(bc),\n        completedAt: read3(bc),\n        rollbackCompletedAt: read3(bc),\n        rollbackError: read1(bc),\n    }\n}\n\nexport function writeEntryMetadata(bc: bare.ByteCursor, x: EntryMetadata): void {\n    writeEntryStatus(bc, x.status)\n    write1(bc, x.error)\n    bare.writeU32(bc, x.attempts)\n    bare.writeU64(bc, x.lastAttemptAt)\n    bare.writeU64(bc, x.createdAt)\n    write3(bc, x.completedAt)\n    write3(bc, x.rollbackCompletedAt)\n    write1(bc, x.rollbackError)\n}\n\nexport function encodeEntryMetadata(x: EntryMetadata): Uint8Array {\n    const bc = new bare.ByteCursor(\n        new Uint8Array(config.initialBufferLength),\n        config\n    )\n    writeEntryMetadata(bc, x)\n    return new Uint8Array(bc.view.buffer, bc.view.byteOffset, bc.offset)\n}\n\nexport function decodeEntryMetadata(bytes: Uint8Array): EntryMetadata {\n    const bc = new bare.ByteCursor(bytes, config)\n    const result = readEntryMetadata(bc)\n    if (bc.offset < bc.view.byteLength) {\n        throw new bare.BareError(bc.offset, \"remaining bytes\")\n    }\n    return result\n}\n\nexport type Message = {\n    readonly id: string,\n    readonly name: string,\n    readonly messageData: Cbor,\n    readonly sentAt: u64,\n}\n\nexport function readMessage(bc: bare.ByteCursor): Message {\n    return {\n        id: bare.readString(bc),\n        name: bare.readString(bc),\n        messageData: readCbor(bc),\n        sentAt: bare.readU64(bc),\n    }\n}\n\nexport function writeMessage(bc: bare.ByteCursor, x: Message): void {\n    bare.writeString(bc, x.id)\n    bare.writeString(bc, x.name)\n    writeCbor(bc, x.messageData)\n    bare.writeU64(bc, x.sentAt)\n}\n\nexport function encodeMessage(x: Message): Uint8Array {\n    const bc = new bare.ByteCursor(\n        new Uint8Array(config.initialBufferLength),\n        config\n    )\n    writeMessage(bc, x)\n    return new Uint8Array(bc.view.buffer, bc.view.byteOffset, bc.offset)\n}\n\nexport function decodeMessage(bytes: Uint8Array): Message {\n    const bc = new bare.ByteCursor(bytes, config)\n    const result = readMessage(bc)\n    if (bc.offset < bc.view.byteLength) {\n        throw new bare.BareError(bc.offset, \"remaining bytes\")\n    }\n    return result\n}\n\nexport enum WorkflowState {\n    PENDING = \"PENDING\",\n    RUNNING = \"RUNNING\",\n    SLEEPING = \"SLEEPING\",\n    FAILED = \"FAILED\",\n    COMPLETED = \"COMPLETED\",\n    ROLLING_BACK = \"ROLLING_BACK\",\n}\n\nexport function readWorkflowState(bc: bare.ByteCursor): WorkflowState {\n    const offset = bc.offset\n    const tag = bare.readU8(bc)\n    switch (tag) {\n        case 0:\n            return WorkflowState.PENDING\n        case 1:\n            return WorkflowState.RUNNING\n        case 2:\n            return WorkflowState.SLEEPING\n        case 3:\n            return WorkflowState.FAILED\n        case 4:\n            return WorkflowState.COMPLETED\n        case 5:\n            return WorkflowState.ROLLING_BACK\n        default: {\n            bc.offset = offset\n            throw new bare.BareError(offset, \"invalid tag\")\n        }\n    }\n}\n\nexport function writeWorkflowState(bc: bare.ByteCursor, x: WorkflowState): void {\n    switch (x) {\n        case WorkflowState.PENDING: {\n            bare.writeU8(bc, 0)\n            break\n        }\n        case WorkflowState.RUNNING: {\n            bare.writeU8(bc, 1)\n            break\n        }\n        case WorkflowState.SLEEPING: {\n            bare.writeU8(bc, 2)\n            break\n        }\n        case WorkflowState.FAILED: {\n            bare.writeU8(bc, 3)\n            break\n        }\n        case WorkflowState.COMPLETED: {\n            bare.writeU8(bc, 4)\n            break\n        }\n        case WorkflowState.ROLLING_BACK: {\n            bare.writeU8(bc, 5)\n            break\n        }\n    }\n}\n\nexport type WorkflowMetadata = {\n    readonly state: WorkflowState,\n    readonly output: Cbor | null,\n    readonly error: string | null,\n    readonly version: string | null,\n}\n\nexport function readWorkflowMetadata(bc: bare.ByteCursor): WorkflowMetadata {\n    return {\n        state: readWorkflowState(bc),\n        output: read0(bc),\n        error: read1(bc),\n        version: read1(bc),\n    }\n}\n\nexport function writeWorkflowMetadata(bc: bare.ByteCursor, x: WorkflowMetadata): void {\n    writeWorkflowState(bc, x.state)\n    write0(bc, x.output)\n    write1(bc, x.error)\n    write1(bc, x.version)\n}\n\nexport function encodeWorkflowMetadata(x: WorkflowMetadata): Uint8Array {\n    const bc = new bare.ByteCursor(\n        new Uint8Array(config.initialBufferLength),\n        config\n    )\n    writeWorkflowMetadata(bc, x)\n    return new Uint8Array(bc.view.buffer, bc.view.byteOffset, bc.offset)\n}\n\nexport function decodeWorkflowMetadata(bytes: Uint8Array): WorkflowMetadata {\n    const bc = new bare.ByteCursor(bytes, config)\n    const result = readWorkflowMetadata(bc)\n    if (bc.offset < bc.view.byteLength) {\n        throw new bare.BareError(bc.offset, \"remaining bytes\")\n    }\n    return result\n}\n\n\nfunction assert(condition: boolean, message?: string): asserts condition {\n    if (!condition) throw new Error(message ?? \"Assertion failed\")\n}\n","import { createVersionedDataHandler } from \"vbare\";\nimport * as v1 from \"../dist/schemas/v1.js\";\n\nexport const CURRENT_VERSION = 1;\n\n// Re-export generated types for convenience\nexport type {\n\tBranchStatus,\n\tEntry,\n\tEntryKind,\n\tEntryMetadata,\n\tJoinEntry,\n\tLocation,\n\tLoopEntry,\n\tLoopIterationMarker,\n\tMessageEntry,\n\tPathSegment,\n\tRaceEntry,\n\tRemovedEntry,\n\tSleepEntry,\n\tStepEntry,\n\tVersionCheckEntry,\n\tWorkflowMetadata,\n} from \"../dist/schemas/v1.js\";\n\nexport {\n\tBranchStatusType,\n\tEntryStatus,\n\tSleepState,\n\tWorkflowState,\n} from \"../dist/schemas/v1.js\";\n\n// === Entry Handler ===\n\nexport const ENTRY_VERSIONED = createVersionedDataHandler<v1.Entry>({\n\tdeserializeVersion: (bytes, version) => {\n\t\tswitch (version) {\n\t\t\tcase 1:\n\t\t\t\treturn v1.decodeEntry(bytes);\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`Unknown Entry version ${version}`);\n\t\t}\n\t},\n\tserializeVersion: (data, version) => {\n\t\tswitch (version) {\n\t\t\tcase 1:\n\t\t\t\treturn v1.encodeEntry(data as v1.Entry);\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`Unknown Entry version ${version}`);\n\t\t}\n\t},\n\tdeserializeConverters: () => [],\n\tserializeConverters: () => [],\n});\n\n// === Entry Metadata Handler ===\n\nexport const ENTRY_METADATA_VERSIONED =\n\tcreateVersionedDataHandler<v1.EntryMetadata>({\n\t\tdeserializeVersion: (bytes, version) => {\n\t\t\tswitch (version) {\n\t\t\t\tcase 1:\n\t\t\t\t\treturn v1.decodeEntryMetadata(bytes);\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new Error(`Unknown EntryMetadata version ${version}`);\n\t\t\t}\n\t\t},\n\t\tserializeVersion: (data, version) => {\n\t\t\tswitch (version) {\n\t\t\t\tcase 1:\n\t\t\t\t\treturn v1.encodeEntryMetadata(data as v1.EntryMetadata);\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new Error(`Unknown EntryMetadata version ${version}`);\n\t\t\t}\n\t\t},\n\t\tdeserializeConverters: () => [],\n\t\tserializeConverters: () => [],\n\t});\n\n// === Workflow Metadata Handler ===\n\nexport const WORKFLOW_METADATA_VERSIONED =\n\tcreateVersionedDataHandler<v1.WorkflowMetadata>({\n\t\tdeserializeVersion: (bytes, version) => {\n\t\t\tswitch (version) {\n\t\t\t\tcase 1:\n\t\t\t\t\treturn v1.decodeWorkflowMetadata(bytes);\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Unknown WorkflowMetadata version ${version}`,\n\t\t\t\t\t);\n\t\t\t}\n\t\t},\n\t\tserializeVersion: (data, version) => {\n\t\t\tswitch (version) {\n\t\t\t\tcase 1:\n\t\t\t\t\treturn v1.encodeWorkflowMetadata(\n\t\t\t\t\t\tdata as v1.WorkflowMetadata,\n\t\t\t\t\t);\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Unknown WorkflowMetadata version ${version}`,\n\t\t\t\t\t);\n\t\t\t}\n\t\t},\n\t\tdeserializeConverters: () => [],\n\t\tserializeConverters: () => [],\n\t});\n","import {\n\tdeserializeEntry,\n\tdeserializeEntryMetadata,\n\tdeserializeName,\n\tdeserializeWorkflowError,\n\tdeserializeWorkflowOutput,\n\tdeserializeWorkflowState,\n\tserializeEntry,\n\tserializeEntryMetadata,\n\tserializeName,\n\tserializeWorkflowError,\n\tserializeWorkflowOutput,\n\tserializeWorkflowState,\n} from \"../schemas/serde.js\";\nimport type { EngineDriver, KVWrite } from \"./driver.js\";\nimport {\n\tbuildEntryMetadataKey,\n\tbuildEntryMetadataPrefix,\n\tbuildHistoryKey,\n\tbuildHistoryPrefix,\n\tbuildHistoryPrefixAll,\n\tbuildNameKey,\n\tbuildNamePrefix,\n\tbuildWorkflowErrorKey,\n\tbuildWorkflowOutputKey,\n\tbuildWorkflowStateKey,\n\tcompareKeys,\n\tparseEntryMetadataKey,\n\tparseNameKey,\n} from \"./keys.js\";\nimport { isLocationPrefix, locationToKey } from \"./location.js\";\nimport type {\n\tEntry,\n\tEntryKind,\n\tEntryMetadata,\n\tLocation,\n\tStorage,\n\tWorkflowEntryMetadataSnapshot,\n\tWorkflowHistoryEntry,\n\tWorkflowHistorySnapshot,\n} from \"./types.js\";\n\nexport const MAX_KV_BATCH_ENTRIES = 128;\nexport const MAX_KV_BATCH_PAYLOAD_BYTES = 976 * 1024;\n\n/**\n * Create an empty storage instance.\n */\nexport function createStorage(): Storage {\n\treturn {\n\t\tnameRegistry: [],\n\t\tflushedNameCount: 0,\n\t\thistory: { entries: new Map() },\n\t\tentryMetadata: new Map(),\n\t\toutput: undefined,\n\t\tstate: \"pending\",\n\t\tflushedState: undefined,\n\t\terror: undefined,\n\t\tflushedError: undefined,\n\t\tflushedOutput: undefined,\n\t};\n}\n\n/**\n * Create a snapshot of workflow history for observers.\n */\nexport function createHistorySnapshot(\n\tstorage: Storage,\n): WorkflowHistorySnapshot {\n\tconst entryMetadata = new Map<string, WorkflowEntryMetadataSnapshot>();\n\tfor (const [id, metadata] of storage.entryMetadata) {\n\t\tconst { dirty, ...rest } = metadata;\n\t\tentryMetadata.set(id, rest);\n\t}\n\n\tconst entries: WorkflowHistoryEntry[] = [];\n\tconst entryKeys = Array.from(storage.history.entries.keys()).sort();\n\tfor (const key of entryKeys) {\n\t\tconst entry = storage.history.entries.get(key);\n\t\tif (!entry) continue;\n\t\tconst { dirty, ...rest } = entry;\n\t\tentries.push(rest);\n\t}\n\n\treturn {\n\t\tnameRegistry: [...storage.nameRegistry],\n\t\tentries,\n\t\tentryMetadata,\n\t};\n}\n\n/**\n * Generate a UUID v4.\n */\nexport function generateId(): string {\n\treturn crypto.randomUUID();\n}\n\n/**\n * Create a new entry.\n */\nexport function createEntry(location: Location, kind: EntryKind): Entry {\n\treturn {\n\t\tid: generateId(),\n\t\tlocation,\n\t\tkind,\n\t\tdirty: true,\n\t};\n}\n\n/**\n * Create or get metadata for an entry.\n */\nexport function getOrCreateMetadata(\n\tstorage: Storage,\n\tentryId: string,\n): EntryMetadata {\n\tlet metadata = storage.entryMetadata.get(entryId);\n\tif (!metadata) {\n\t\tmetadata = {\n\t\t\tstatus: \"pending\",\n\t\t\tattempts: 0,\n\t\t\tlastAttemptAt: 0,\n\t\t\tcreatedAt: Date.now(),\n\t\t\trollbackCompletedAt: undefined,\n\t\t\trollbackError: undefined,\n\t\t\tdirty: true,\n\t\t};\n\t\tstorage.entryMetadata.set(entryId, metadata);\n\t}\n\treturn metadata;\n}\n\n/**\n * Load storage from the driver.\n */\nexport async function loadStorage(driver: EngineDriver): Promise<Storage> {\n\tconst storage = createStorage();\n\n\t// Load name registry\n\tconst nameEntries = await driver.list(buildNamePrefix());\n\t// Sort by index to ensure correct order\n\tnameEntries.sort((a, b) => compareKeys(a.key, b.key));\n\tfor (const entry of nameEntries) {\n\t\tconst index = parseNameKey(entry.key);\n\t\tstorage.nameRegistry[index] = deserializeName(entry.value);\n\t}\n\t// Track how many names are already persisted\n\tstorage.flushedNameCount = storage.nameRegistry.length;\n\n\t// Load history entries\n\tconst historyEntries = await driver.list(buildHistoryPrefixAll());\n\tfor (const entry of historyEntries) {\n\t\tconst parsed = deserializeEntry(entry.value);\n\t\tparsed.dirty = false;\n\t\t// Use locationToKey to match how context.ts looks up entries\n\t\tconst key = locationToKey(storage, parsed.location);\n\t\tstorage.history.entries.set(key, parsed);\n\t}\n\n\t// Load entry metadata so observers can reconstruct workflow state after\n\t// the actor wakes and rebuilds storage from persisted history.\n\tconst metadataEntries = await driver.list(buildEntryMetadataPrefix());\n\tfor (const entry of metadataEntries) {\n\t\tconst entryId = parseEntryMetadataKey(entry.key);\n\t\tconst metadata = deserializeEntryMetadata(entry.value);\n\t\tmetadata.dirty = false;\n\t\tstorage.entryMetadata.set(entryId, metadata);\n\t}\n\n\t// Load workflow state\n\tconst stateValue = await driver.get(buildWorkflowStateKey());\n\tif (stateValue) {\n\t\tstorage.state = deserializeWorkflowState(stateValue);\n\t\tstorage.flushedState = storage.state;\n\t}\n\n\t// Load output if present\n\tconst outputValue = await driver.get(buildWorkflowOutputKey());\n\tif (outputValue) {\n\t\tstorage.output = deserializeWorkflowOutput(outputValue);\n\t\tstorage.flushedOutput = storage.output;\n\t}\n\n\t// Load error if present\n\tconst errorValue = await driver.get(buildWorkflowErrorKey());\n\tif (errorValue) {\n\t\tstorage.error = deserializeWorkflowError(errorValue);\n\t\tstorage.flushedError = storage.error;\n\t}\n\n\treturn storage;\n}\n\n/**\n * Load metadata for an entry (lazy loading).\n */\nexport async function loadMetadata(\n\tstorage: Storage,\n\tdriver: EngineDriver,\n\tentryId: string,\n): Promise<EntryMetadata> {\n\t// Check if already loaded\n\tconst existing = storage.entryMetadata.get(entryId);\n\tif (existing) {\n\t\treturn existing;\n\t}\n\n\t// Load from driver\n\tconst value = await driver.get(buildEntryMetadataKey(entryId));\n\tif (value) {\n\t\tconst metadata = deserializeEntryMetadata(value);\n\t\tmetadata.dirty = false;\n\t\tstorage.entryMetadata.set(entryId, metadata);\n\t\treturn metadata;\n\t}\n\n\t// Create new metadata\n\treturn getOrCreateMetadata(storage, entryId);\n}\n\n/**\n * Pending deletions collected by collectLoopPruning to be included\n * in the next flush alongside the state write.\n */\nexport interface PendingDeletions {\n\tprefixes: Uint8Array[];\n\tkeys: Uint8Array[];\n\tranges: { start: Uint8Array; end: Uint8Array }[];\n}\n\n/**\n * Flush all dirty data to the driver. Optionally includes pending\n * deletions so that history pruning happens alongside the\n * state write.\n */\nexport async function flush(\n\tstorage: Storage,\n\tdriver: EngineDriver,\n\tonHistoryUpdated?: () => void,\n\tpendingDeletions?: PendingDeletions,\n): Promise<void> {\n\tconst writes: KVWrite[] = [];\n\tconst dirtyEntries: Entry[] = [];\n\tconst dirtyMetadata: EntryMetadata[] = [];\n\tlet historyUpdated = false;\n\n\t// Flush only new names (those added since last flush)\n\tfor (\n\t\tlet i = storage.flushedNameCount;\n\t\ti < storage.nameRegistry.length;\n\t\ti++\n\t) {\n\t\tconst name = storage.nameRegistry[i];\n\t\tif (name !== undefined) {\n\t\t\twrites.push({\n\t\t\t\tkey: buildNameKey(i),\n\t\t\t\tvalue: serializeName(name),\n\t\t\t});\n\t\t\thistoryUpdated = true;\n\t\t}\n\t}\n\n\t// Flush dirty entries\n\tfor (const [, entry] of storage.history.entries) {\n\t\tif (entry.dirty) {\n\t\t\twrites.push({\n\t\t\t\tkey: buildHistoryKey(entry.location),\n\t\t\t\tvalue: serializeEntry(entry),\n\t\t\t});\n\t\t\tdirtyEntries.push(entry);\n\t\t\thistoryUpdated = true;\n\t\t}\n\t}\n\n\t// Flush dirty metadata\n\tfor (const [id, metadata] of storage.entryMetadata) {\n\t\tif (metadata.dirty) {\n\t\t\twrites.push({\n\t\t\t\tkey: buildEntryMetadataKey(id),\n\t\t\t\tvalue: serializeEntryMetadata(metadata),\n\t\t\t});\n\t\t\tdirtyMetadata.push(metadata);\n\t\t\thistoryUpdated = true;\n\t\t}\n\t}\n\n\t// Flush workflow state if changed\n\tif (storage.state !== storage.flushedState) {\n\t\twrites.push({\n\t\t\tkey: buildWorkflowStateKey(),\n\t\t\tvalue: serializeWorkflowState(storage.state),\n\t\t});\n\t}\n\n\t// Flush output if changed\n\tif (\n\t\tstorage.output !== undefined &&\n\t\tstorage.output !== storage.flushedOutput\n\t) {\n\t\twrites.push({\n\t\t\tkey: buildWorkflowOutputKey(),\n\t\t\tvalue: serializeWorkflowOutput(storage.output),\n\t\t});\n\t}\n\n\t// Flush error if changed (compare by message since objects aren't reference-equal)\n\tconst errorChanged =\n\t\tstorage.error !== undefined &&\n\t\t(storage.flushedError === undefined ||\n\t\t\tstorage.error.name !== storage.flushedError.name ||\n\t\t\tstorage.error.message !== storage.flushedError.message);\n\tif (errorChanged) {\n\t\twrites.push({\n\t\t\tkey: buildWorkflowErrorKey(),\n\t\t\tvalue: serializeWorkflowError(storage.error!),\n\t\t});\n\t}\n\n\tif (writes.length > 0) {\n\t\tif (driver.atomicBatch) {\n\t\t\tawait driver.batch(writes);\n\t\t} else {\n\t\t\tfor (const chunk of splitBatchWrites(writes)) {\n\t\t\t\tawait driver.batch(chunk);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Apply pending deletions after the batch write. These are collected\n\t// by collectLoopPruning so pruning happens alongside the state write.\n\tif (pendingDeletions) {\n\t\tconst deleteOps: Promise<void>[] = [];\n\t\tfor (const prefix of pendingDeletions.prefixes) {\n\t\t\tdeleteOps.push(driver.deletePrefix(prefix));\n\t\t}\n\t\tfor (const range of pendingDeletions.ranges) {\n\t\t\tdeleteOps.push(driver.deleteRange(range.start, range.end));\n\t\t}\n\t\tfor (const key of pendingDeletions.keys) {\n\t\t\tdeleteOps.push(driver.delete(key));\n\t\t}\n\t\tif (deleteOps.length > 0) {\n\t\t\tawait Promise.all(deleteOps);\n\t\t\thistoryUpdated = true;\n\t\t}\n\t}\n\n\t// Update flushed tracking after successful write\n\tfor (const entry of dirtyEntries) {\n\t\tentry.dirty = false;\n\t}\n\tfor (const metadata of dirtyMetadata) {\n\t\tmetadata.dirty = false;\n\t}\n\tstorage.flushedNameCount = storage.nameRegistry.length;\n\tstorage.flushedState = storage.state;\n\tstorage.flushedOutput = storage.output;\n\tstorage.flushedError = storage.error;\n\n\tif (historyUpdated && onHistoryUpdated) {\n\t\tonHistoryUpdated();\n\t}\n}\n\nfunction splitBatchWrites(writes: KVWrite[]): KVWrite[][] {\n\tconst chunks: KVWrite[][] = [];\n\tlet chunk: KVWrite[] = [];\n\tlet chunkBytes = 0;\n\n\tfor (const write of writes) {\n\t\tconst writeBytes = write.key.byteLength + write.value.byteLength;\n\t\tif (writeBytes > MAX_KV_BATCH_PAYLOAD_BYTES) {\n\t\t\tthrow new Error(\n\t\t\t\t`KV batch write is ${writeBytes} bytes, exceeding the ${MAX_KV_BATCH_PAYLOAD_BYTES} byte limit`,\n\t\t\t);\n\t\t}\n\n\t\tif (\n\t\t\tchunk.length >= MAX_KV_BATCH_ENTRIES ||\n\t\t\t(chunk.length > 0 &&\n\t\t\t\tchunkBytes + writeBytes > MAX_KV_BATCH_PAYLOAD_BYTES)\n\t\t) {\n\t\t\tchunks.push(chunk);\n\t\t\tchunk = [];\n\t\t\tchunkBytes = 0;\n\t\t}\n\n\t\tchunk.push(write);\n\t\tchunkBytes += writeBytes;\n\t}\n\n\tif (chunk.length > 0) {\n\t\tchunks.push(chunk);\n\t}\n\n\treturn chunks;\n}\n\n/**\n * Delete entries with a given location prefix (used for loop forgetting).\n * Also cleans up associated metadata from both memory and driver.\n */\nexport async function deleteEntriesWithPrefix(\n\tstorage: Storage,\n\tdriver: EngineDriver,\n\tprefixLocation: Location,\n\tonHistoryUpdated?: () => void,\n): Promise<void> {\n\tconst deletions = collectDeletionsForPrefix(storage, prefixLocation);\n\n\t// Apply deletions to driver\n\tawait driver.deletePrefix(deletions.prefixes[0]!);\n\tawait Promise.all(deletions.keys.map((key) => driver.delete(key)));\n\n\tif (deletions.keys.length > 0 && onHistoryUpdated) {\n\t\tonHistoryUpdated();\n\t}\n}\n\n/**\n * Remove entries matching a location prefix from memory and collect\n * the driver-level deletion operations. The returned PendingDeletions\n * can be applied immediately or batched with a flush.\n */\nexport function collectDeletionsForPrefix(\n\tstorage: Storage,\n\tprefixLocation: Location,\n): PendingDeletions {\n\tconst pending: PendingDeletions = {\n\t\tprefixes: [buildHistoryPrefix(prefixLocation)],\n\t\tkeys: [],\n\t\tranges: [],\n\t};\n\n\tfor (const [key, entry] of storage.history.entries) {\n\t\tif (isLocationPrefix(prefixLocation, entry.location)) {\n\t\t\tpending.keys.push(buildEntryMetadataKey(entry.id));\n\t\t\tstorage.entryMetadata.delete(entry.id);\n\t\t\tstorage.history.entries.delete(key);\n\t\t}\n\t}\n\n\treturn pending;\n}\n\n/**\n * Get an entry by location.\n */\nexport function getEntry(\n\tstorage: Storage,\n\tlocation: Location,\n): Entry | undefined {\n\tconst key = locationToKey(storage, location);\n\treturn storage.history.entries.get(key);\n}\n\n/**\n * Set an entry by location.\n */\nexport function setEntry(\n\tstorage: Storage,\n\tlocation: Location,\n\tentry: Entry,\n): void {\n\tconst key = locationToKey(storage, location);\n\tstorage.history.entries.set(key, entry);\n}\n","import type { Logger } from \"pino\";\nimport type { EngineDriver } from \"./driver.js\";\nimport {\n\textractErrorInfo,\n\tgetErrorEventTag,\n\tmarkErrorReported,\n} from \"./error-utils.js\";\nimport {\n\tCancelledError,\n\tCriticalError,\n\tEntryInProgressError,\n\tEvictedError,\n\tHistoryDivergedError,\n\tJoinError,\n\tMessageWaitError,\n\tRaceError,\n\tRollbackCheckpointError,\n\tRollbackError,\n\tRollbackStopError,\n\tSleepError,\n\tStepExhaustedError,\n\tStepFailedError,\n} from \"./errors.js\";\nimport { buildEntryMetadataKey, buildLoopIterationRange } from \"./keys.js\";\nimport {\n\tappendLoopIteration,\n\tappendName,\n\temptyLocation,\n\tisLocationPrefix,\n\tlocationToKey,\n\tregisterName,\n} from \"./location.js\";\nimport {\n\tcreateEntry,\n\tdeleteEntriesWithPrefix,\n\tflush,\n\tgetOrCreateMetadata,\n\tloadMetadata,\n\ttype PendingDeletions,\n\tsetEntry,\n} from \"./storage.js\";\nimport type {\n\tBranchConfig,\n\tBranchOutput,\n\tEntry,\n\tEntryKindType,\n\tEntryMetadata,\n\tLocation,\n\tLoopConfig,\n\tLoopIterationResult,\n\tLoopResult,\n\tMessage,\n\tRollbackContextInterface,\n\tStepConfig,\n\tStorage,\n\tTryBlockCatchKind,\n\tTryBlockConfig,\n\tTryBlockFailure,\n\tTryBlockResult,\n\tTryStepCatchKind,\n\tTryStepConfig,\n\tTryStepFailure,\n\tTryStepResult,\n\tWorkflowContextInterface,\n\tWorkflowError,\n\tWorkflowErrorEvent,\n\tWorkflowErrorHandler,\n\tWorkflowMessageDriver,\n\tWorkflowQueue,\n\tWorkflowQueueMessage,\n\tWorkflowQueueNextBatchOptions,\n\tWorkflowQueueNextOptions,\n} from \"./types.js\";\n\n/**\n * Default values for step configuration.\n * These are exported so users can reference them when overriding.\n */\nexport const DEFAULT_MAX_RETRIES = 3;\nexport const DEFAULT_RETRY_BACKOFF_BASE = 100;\nexport const DEFAULT_RETRY_BACKOFF_MAX = 30000;\nexport const DEFAULT_LOOP_HISTORY_PRUNE_INTERVAL = 20;\nexport const DEFAULT_STEP_TIMEOUT = 30000; // 30 seconds\nconst DEFAULT_TRY_STEP_CATCH: readonly TryStepCatchKind[] = [\n\t\"critical\",\n\t\"timeout\",\n\t\"exhausted\",\n];\nconst DEFAULT_TRY_BLOCK_CATCH: readonly TryBlockCatchKind[] = [\n\t\"step\",\n\t\"join\",\n\t\"race\",\n];\n\nconst QUEUE_HISTORY_MESSAGE_MARKER = \"__rivetWorkflowQueueMessage\";\nconst TRY_STEP_FAILURE_SYMBOL = Symbol(\"workflow.try-step.failure\");\nconst TRY_BLOCK_FAILURE_SYMBOL = Symbol(\"workflow.try-block.failure\");\n\n/**\n * Calculate backoff delay with exponential backoff.\n * Uses deterministic calculation (no jitter) for replay consistency.\n */\nfunction calculateBackoff(attempts: number, base: number, max: number): number {\n\t// Exponential backoff without jitter for determinism\n\treturn Math.min(max, base * 2 ** attempts);\n}\n\n/**\n * Error thrown when a step times out.\n */\nexport class StepTimeoutError extends Error {\n\tconstructor(\n\t\tpublic readonly stepName: string,\n\t\tpublic readonly timeoutMs: number,\n\t) {\n\t\tsuper(`Step \"${stepName}\" timed out after ${timeoutMs}ms`);\n\t\tthis.name = \"StepTimeoutError\";\n\t}\n}\n\ntype SchedulerYieldState = {\n\tdeadline?: number;\n\tmessageNames: Set<string>;\n};\n\ntype TryBlockFailureInfo = Pick<TryBlockFailure, \"source\" | \"name\">;\n\nfunction attachTryStepFailure<T extends Error>(\n\terror: T,\n\tfailure: TryStepFailure,\n): T {\n\t(\n\t\terror as T & {\n\t\t\t[TRY_STEP_FAILURE_SYMBOL]?: TryStepFailure;\n\t\t}\n\t)[TRY_STEP_FAILURE_SYMBOL] = failure;\n\treturn error;\n}\n\nfunction readTryStepFailure(error: unknown): TryStepFailure | undefined {\n\tif (!(error instanceof Error)) {\n\t\treturn undefined;\n\t}\n\n\treturn (\n\t\terror as Error & {\n\t\t\t[TRY_STEP_FAILURE_SYMBOL]?: TryStepFailure;\n\t\t}\n\t)[TRY_STEP_FAILURE_SYMBOL];\n}\n\nfunction attachTryBlockFailure<T extends Error>(\n\terror: T,\n\tfailure: TryBlockFailureInfo,\n): T {\n\t(\n\t\terror as T & {\n\t\t\t[TRY_BLOCK_FAILURE_SYMBOL]?: TryBlockFailureInfo;\n\t\t}\n\t)[TRY_BLOCK_FAILURE_SYMBOL] = failure;\n\treturn error;\n}\n\nfunction readTryBlockFailure(error: unknown): TryBlockFailureInfo | undefined {\n\tif (!(error instanceof Error)) {\n\t\treturn undefined;\n\t}\n\n\treturn (\n\t\terror as Error & {\n\t\t\t[TRY_BLOCK_FAILURE_SYMBOL]?: TryBlockFailureInfo;\n\t\t}\n\t)[TRY_BLOCK_FAILURE_SYMBOL];\n}\n\nfunction shouldRethrowTryError(error: unknown): boolean {\n\treturn (\n\t\terror instanceof StepFailedError ||\n\t\terror instanceof SleepError ||\n\t\terror instanceof MessageWaitError ||\n\t\terror instanceof EvictedError ||\n\t\terror instanceof HistoryDivergedError ||\n\t\terror instanceof EntryInProgressError ||\n\t\terror instanceof RollbackCheckpointError ||\n\t\terror instanceof RollbackStopError\n\t);\n}\n\nfunction shouldCatchTryStepFailure(\n\tfailure: TryStepFailure,\n\tcatchKinds?: readonly TryStepCatchKind[],\n): boolean {\n\tconst effectiveCatch = catchKinds ?? DEFAULT_TRY_STEP_CATCH;\n\treturn effectiveCatch.includes(failure.kind);\n}\n\nfunction shouldCatchTryBlockFailure(\n\tfailure: TryBlockFailure,\n\tcatchKinds?: readonly TryBlockCatchKind[],\n): boolean {\n\tconst effectiveCatch = catchKinds ?? DEFAULT_TRY_BLOCK_CATCH;\n\n\tif (failure.source === \"step\") {\n\t\treturn failure.step?.kind === \"rollback\"\n\t\t\t? effectiveCatch.includes(\"rollback\")\n\t\t\t: effectiveCatch.includes(\"step\");\n\t}\n\tif (failure.source === \"join\") {\n\t\treturn effectiveCatch.includes(\"join\");\n\t}\n\tif (failure.source === \"race\") {\n\t\treturn effectiveCatch.includes(\"race\");\n\t}\n\treturn effectiveCatch.includes(\"rollback\");\n}\n\nfunction parseStoredWorkflowError(message: string | undefined): WorkflowError {\n\tif (!message) {\n\t\treturn {\n\t\t\tname: \"Error\",\n\t\t\tmessage: \"unknown error\",\n\t\t};\n\t}\n\n\tconst match = /^([^:]+):\\s*(.*)$/s.exec(message);\n\tif (!match) {\n\t\treturn {\n\t\t\tname: \"Error\",\n\t\t\tmessage,\n\t\t};\n\t}\n\n\treturn {\n\t\tname: match[1],\n\t\tmessage: match[2],\n\t};\n}\n\nfunction getTryStepFailureFromExhaustedError(\n\tstepName: string,\n\tattempts: number,\n\terror: StepExhaustedError,\n): TryStepFailure {\n\treturn {\n\t\tkind: \"exhausted\",\n\t\tstepName,\n\t\tattempts,\n\t\terror: parseStoredWorkflowError(error.lastError),\n\t};\n}\n\nfunction mergeSchedulerYield(\n\tstate: SchedulerYieldState | undefined,\n\terror: SleepError | MessageWaitError | StepFailedError,\n): SchedulerYieldState {\n\tconst nextState: SchedulerYieldState = state ?? {\n\t\tmessageNames: new Set<string>(),\n\t};\n\n\tif (error instanceof SleepError) {\n\t\tnextState.deadline =\n\t\t\tnextState.deadline === undefined\n\t\t\t\t? error.deadline\n\t\t\t\t: Math.min(nextState.deadline, error.deadline);\n\t\tfor (const messageName of error.messageNames ?? []) {\n\t\t\tnextState.messageNames.add(messageName);\n\t\t}\n\t\treturn nextState;\n\t}\n\n\tif (error instanceof MessageWaitError) {\n\t\tfor (const messageName of error.messageNames) {\n\t\t\tnextState.messageNames.add(messageName);\n\t\t}\n\t\treturn nextState;\n\t}\n\n\tnextState.deadline =\n\t\tnextState.deadline === undefined\n\t\t\t? error.retryAt\n\t\t\t: Math.min(nextState.deadline, error.retryAt);\n\treturn nextState;\n}\n\nfunction buildSchedulerYieldError(\n\tstate: SchedulerYieldState,\n): SleepError | MessageWaitError {\n\tconst messageNames = [...state.messageNames];\n\tif (state.deadline !== undefined) {\n\t\treturn new SleepError(\n\t\t\tstate.deadline,\n\t\t\tmessageNames.length > 0 ? messageNames : undefined,\n\t\t);\n\t}\n\treturn new MessageWaitError(messageNames);\n}\n\nfunction controlFlowErrorPriority(error: Error): number {\n\tif (error instanceof EvictedError) {\n\t\treturn 0;\n\t}\n\tif (error instanceof HistoryDivergedError) {\n\t\treturn 1;\n\t}\n\tif (error instanceof EntryInProgressError) {\n\t\treturn 2;\n\t}\n\tif (error instanceof RollbackCheckpointError) {\n\t\treturn 3;\n\t}\n\tif (error instanceof RollbackStopError) {\n\t\treturn 4;\n\t}\n\treturn 5;\n}\n\nfunction selectControlFlowError(\n\tcurrent: Error | undefined,\n\tcandidate: Error,\n): Error {\n\tif (!current) {\n\t\treturn candidate;\n\t}\n\treturn controlFlowErrorPriority(candidate) <\n\t\tcontrolFlowErrorPriority(current)\n\t\t? candidate\n\t\t: current;\n}\n\n/**\n * Internal representation of a rollback handler.\n */\nexport interface RollbackAction<T = unknown> {\n\tentryId: string;\n\tname: string;\n\toutput: T;\n\trollback: (ctx: RollbackContextInterface, output: T) => Promise<void>;\n}\n\n/**\n * Internal implementation of WorkflowContext.\n */\nexport class WorkflowContextImpl implements WorkflowContextInterface {\n\tprivate entryInProgress = false;\n\tprivate abortController: AbortController;\n\tprivate currentLocation: Location;\n\tprivate visitedKeys: Set<string>;\n\tprivate mode: \"forward\" | \"rollback\";\n\tprivate rollbackActions?: RollbackAction[];\n\tprivate rollbackCheckpointSet: boolean;\n\t/** Track names used in current execution to detect duplicates */\n\tprivate usedNamesInExecution = new Set<string>();\n\tprivate pendingCompletableMessageIds = new Set<string>();\n\tprivate historyNotifier?: () => void;\n\tprivate onError?: WorkflowErrorHandler;\n\tprivate logger?: Logger;\n\n\tconstructor(\n\t\tpublic readonly workflowId: string,\n\t\tprivate storage: Storage,\n\t\tprivate driver: EngineDriver,\n\t\tprivate messageDriver: WorkflowMessageDriver,\n\t\tlocation: Location = emptyLocation(),\n\t\tabortController?: AbortController,\n\t\tmode: \"forward\" | \"rollback\" = \"forward\",\n\t\trollbackActions?: RollbackAction[],\n\t\trollbackCheckpointSet = false,\n\t\thistoryNotifier?: () => void,\n\t\tonError?: WorkflowErrorHandler,\n\t\tlogger?: Logger,\n\t\tvisitedKeys?: Set<string>,\n\t) {\n\t\tthis.currentLocation = location;\n\t\tthis.abortController = abortController ?? new AbortController();\n\t\tthis.mode = mode;\n\t\tthis.rollbackActions = rollbackActions;\n\t\tthis.rollbackCheckpointSet = rollbackCheckpointSet;\n\t\tthis.historyNotifier = historyNotifier;\n\t\tthis.onError = onError;\n\t\tthis.logger = logger;\n\t\tthis.visitedKeys = visitedKeys ?? new Set();\n\t}\n\n\tget abortSignal(): AbortSignal {\n\t\treturn this.abortController.signal;\n\t}\n\n\tget queue(): WorkflowQueue {\n\t\treturn {\n\t\t\tnext: async (name, opts) => await this.queueNext(name, opts),\n\t\t\tnextBatch: async (name, opts) =>\n\t\t\t\tawait this.queueNextBatch(name, opts),\n\t\t\tsend: async (name, body) => await this.queueSend(name, body),\n\t\t};\n\t}\n\n\tisEvicted(): boolean {\n\t\treturn this.abortSignal.aborted;\n\t}\n\n\tprivate assertNotInProgress(): void {\n\t\tif (this.entryInProgress) {\n\t\t\tthrow new EntryInProgressError();\n\t\t}\n\t}\n\n\tprivate checkEvicted(): void {\n\t\tif (this.abortSignal.aborted) {\n\t\t\tthrow new EvictedError();\n\t\t}\n\t}\n\n\tprivate async flushStorage(): Promise<void> {\n\t\tawait flush(this.storage, this.driver, this.historyNotifier);\n\t}\n\n\t/**\n\t * Create a new branch context for parallel/nested execution.\n\t */\n\tcreateBranch(\n\t\tlocation: Location,\n\t\tabortController?: AbortController,\n\t): WorkflowContextImpl {\n\t\treturn new WorkflowContextImpl(\n\t\t\tthis.workflowId,\n\t\t\tthis.storage,\n\t\t\tthis.driver,\n\t\t\tthis.messageDriver,\n\t\t\tlocation,\n\t\t\tabortController ?? this.abortController,\n\t\t\tthis.mode,\n\t\t\tthis.rollbackActions,\n\t\t\tthis.rollbackCheckpointSet,\n\t\t\tthis.historyNotifier,\n\t\t\tthis.onError,\n\t\t\tthis.logger,\n\t\t\tthis.visitedKeys,\n\t\t);\n\t}\n\n\t/**\n\t * Log a debug message using the configured logger.\n\t */\n\tprivate log(\n\t\tlevel: \"debug\" | \"info\" | \"warn\" | \"error\",\n\t\tdata: Record<string, unknown>,\n\t): void {\n\t\tif (!this.logger) return;\n\t\tthis.logger[level](data);\n\t}\n\n\tprivate async notifyError(event: WorkflowErrorEvent): Promise<void> {\n\t\tif (!this.onError) {\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tawait this.onError(event);\n\t\t} catch (error) {\n\t\t\tthis.log(\"warn\", {\n\t\t\t\tmsg: \"workflow error hook failed\",\n\t\t\t\thookEventType: getErrorEventTag(event),\n\t\t\t\terror: extractErrorInfo(error),\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate async notifyStepError<T>(\n\t\tconfig: StepConfig<T>,\n\t\tattempt: number,\n\t\terror: unknown,\n\t\topts: {\n\t\t\twillRetry: boolean;\n\t\t\tretryDelay?: number;\n\t\t\tretryAt?: number;\n\t\t},\n\t): Promise<void> {\n\t\tconst maxRetries = config.maxRetries ?? DEFAULT_MAX_RETRIES;\n\t\tawait this.notifyError({\n\t\t\tstep: {\n\t\t\t\tworkflowId: this.workflowId,\n\t\t\t\tstepName: config.name,\n\t\t\t\tattempt,\n\t\t\t\tmaxRetries,\n\t\t\t\tremainingRetries: Math.max(0, maxRetries - (attempt - 1)),\n\t\t\t\twillRetry: opts.willRetry,\n\t\t\t\tretryDelay: opts.retryDelay,\n\t\t\t\tretryAt: opts.retryAt,\n\t\t\t\terror: extractErrorInfo(error),\n\t\t\t},\n\t\t});\n\t}\n\n\t/**\n\t * Mark a key as visited.\n\t */\n\tprivate markVisited(key: string): void {\n\t\tthis.visitedKeys.add(key);\n\t}\n\n\t/**\n\t * Check if a name has already been used at the current location in this execution.\n\t * Throws HistoryDivergedError if duplicate detected.\n\t */\n\tprivate checkDuplicateName(name: string): void {\n\t\tconst fullKey = `${locationToKey(this.storage, this.currentLocation)}/${name}`;\n\t\tif (this.usedNamesInExecution.has(fullKey)) {\n\t\t\tthrow new HistoryDivergedError(\n\t\t\t\t`Duplicate entry name \"${name}\" at location \"${locationToKey(this.storage, this.currentLocation)}\". ` +\n\t\t\t\t\t`Each step/loop/sleep/queue.next/join/race must have a unique name within its scope.`,\n\t\t\t);\n\t\t}\n\t\tthis.usedNamesInExecution.add(fullKey);\n\t}\n\n\tprivate stopRollback(): never {\n\t\tthrow new RollbackStopError();\n\t}\n\n\tprivate stopRollbackIfMissing(entry: Entry | undefined): void {\n\t\tif (this.mode === \"rollback\" && !entry) {\n\t\t\tthis.stopRollback();\n\t\t}\n\t}\n\n\tprivate stopRollbackIfIncomplete(condition: boolean): void {\n\t\tif (this.mode === \"rollback\" && condition) {\n\t\t\tthis.stopRollback();\n\t\t}\n\t}\n\n\tprivate registerRollbackAction<T>(\n\t\tconfig: StepConfig<T>,\n\t\tentryId: string,\n\t\toutput: T,\n\t\tmetadata: EntryMetadata,\n\t): void {\n\t\tif (!config.rollback) {\n\t\t\treturn;\n\t\t}\n\t\tif (metadata.rollbackCompletedAt !== undefined) {\n\t\t\treturn;\n\t\t}\n\t\tthis.rollbackActions?.push({\n\t\t\tentryId,\n\t\t\tname: config.name,\n\t\t\toutput: output as unknown,\n\t\t\trollback: config.rollback as (\n\t\t\t\tctx: RollbackContextInterface,\n\t\t\t\toutput: unknown,\n\t\t\t) => Promise<void>,\n\t\t});\n\t}\n\n\t/**\n\t * Ensure a rollback checkpoint exists before registering rollback handlers.\n\t */\n\tprivate ensureRollbackCheckpoint<T>(config: StepConfig<T>): void {\n\t\tif (!config.rollback) {\n\t\t\treturn;\n\t\t}\n\t\tif (!this.rollbackCheckpointSet) {\n\t\t\tthrow new RollbackCheckpointError();\n\t\t}\n\t}\n\n\t/**\n\t * Validate that all expected entries in the branch were visited.\n\t * Throws HistoryDivergedError if there are unvisited entries.\n\t */\n\tvalidateComplete(): void {\n\t\tconst prefix = locationToKey(this.storage, this.currentLocation);\n\n\t\tfor (const key of this.storage.history.entries.keys()) {\n\t\t\t// Check if this key is under our current location prefix\n\t\t\t// Handle root prefix (empty string) specially - all keys are under root\n\t\t\tconst isUnderPrefix =\n\t\t\t\tprefix === \"\"\n\t\t\t\t\t? true // Root: all keys are children\n\t\t\t\t\t: key.startsWith(`${prefix}/`) || key === prefix;\n\n\t\t\tif (isUnderPrefix) {\n\t\t\t\tif (!this.visitedKeys.has(key)) {\n\t\t\t\t\t// Entry exists in history but wasn't visited\n\t\t\t\t\t// This means workflow code may have changed\n\t\t\t\t\tthrow new HistoryDivergedError(\n\t\t\t\t\t\t`Entry \"${key}\" exists in history but was not visited. ` +\n\t\t\t\t\t\t\t`Workflow code may have changed. Use ctx.removed() to handle migrations.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Evict the workflow.\n\t */\n\tevict(): void {\n\t\tthis.abortController.abort(new EvictedError());\n\t}\n\n\t/**\n\t * Wait for `ms`, rejecting early with EvictedError if the workflow is\n\t * evicted. Both the timer and the abort listener are torn down on either\n\t * outcome, so a completed sleep never leaves a dangling listener on the\n\t * long-lived run abort signal.\n\t */\n\tprivate async sleepOrEvict(ms: number): Promise<void> {\n\t\tif (this.abortSignal.aborted) {\n\t\t\tthrow new EvictedError();\n\t\t}\n\t\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\t\tlet onAbort: (() => void) | undefined;\n\t\ttry {\n\t\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\t\ttimer = setTimeout(resolve, ms);\n\t\t\t\tonAbort = () => reject(new EvictedError());\n\t\t\t\tthis.abortSignal.addEventListener(\"abort\", onAbort, {\n\t\t\t\t\tonce: true,\n\t\t\t\t});\n\t\t\t});\n\t\t} finally {\n\t\t\tif (timer !== undefined) {\n\t\t\t\tclearTimeout(timer);\n\t\t\t}\n\t\t\tif (onAbort) {\n\t\t\t\tthis.abortSignal.removeEventListener(\"abort\", onAbort);\n\t\t\t}\n\t\t}\n\t}\n\n\t// === Step ===\n\n\tasync step<T>(\n\t\tnameOrConfig: string | StepConfig<T>,\n\t\trun?: () => Promise<T>,\n\t): Promise<T> {\n\t\tthis.assertNotInProgress();\n\t\tthis.checkEvicted();\n\n\t\tconst config: StepConfig<T> =\n\t\t\ttypeof nameOrConfig === \"string\"\n\t\t\t\t? { name: nameOrConfig, run: run! }\n\t\t\t\t: nameOrConfig;\n\n\t\tthis.entryInProgress = true;\n\t\ttry {\n\t\t\treturn await this.executeStep(config);\n\t\t} finally {\n\t\t\tthis.entryInProgress = false;\n\t\t}\n\t}\n\n\tasync tryStep<T>(\n\t\tnameOrConfig: string | TryStepConfig<T>,\n\t\trun?: () => Promise<T>,\n\t): Promise<TryStepResult<T>> {\n\t\tconst config =\n\t\t\ttypeof nameOrConfig === \"string\"\n\t\t\t\t? ({\n\t\t\t\t\t\tname: nameOrConfig,\n\t\t\t\t\t\trun: run!,\n\t\t\t\t\t} satisfies TryStepConfig<T>)\n\t\t\t\t: nameOrConfig;\n\n\t\ttry {\n\t\t\treturn {\n\t\t\t\tok: true,\n\t\t\t\tvalue: await this.step(config),\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tif (shouldRethrowTryError(error)) {\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\tconst failure = readTryStepFailure(error);\n\t\t\tif (!failure || !shouldCatchTryStepFailure(failure, config.catch)) {\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\tfailure,\n\t\t\t};\n\t\t}\n\t}\n\n\tasync try<T>(\n\t\tnameOrConfig: string | TryBlockConfig<T>,\n\t\trun?: (ctx: WorkflowContextInterface) => Promise<T>,\n\t): Promise<TryBlockResult<T>> {\n\t\tthis.assertNotInProgress();\n\t\tthis.checkEvicted();\n\n\t\tconst config =\n\t\t\ttypeof nameOrConfig === \"string\"\n\t\t\t\t? ({\n\t\t\t\t\t\tname: nameOrConfig,\n\t\t\t\t\t\trun: run!,\n\t\t\t\t\t} satisfies TryBlockConfig<T>)\n\t\t\t\t: nameOrConfig;\n\n\t\tthis.entryInProgress = true;\n\t\ttry {\n\t\t\treturn await this.executeTry(config);\n\t\t} finally {\n\t\t\tthis.entryInProgress = false;\n\t\t}\n\t}\n\n\tprivate async executeTry<T>(\n\t\tconfig: TryBlockConfig<T>,\n\t): Promise<TryBlockResult<T>> {\n\t\tthis.checkDuplicateName(config.name);\n\n\t\tconst location = appendName(\n\t\t\tthis.storage,\n\t\t\tthis.currentLocation,\n\t\t\tconfig.name,\n\t\t);\n\t\tconst blockCtx = this.createBranch(location);\n\n\t\ttry {\n\t\t\tconst value = await config.run(blockCtx);\n\t\t\tblockCtx.validateComplete();\n\t\t\treturn {\n\t\t\t\tok: true,\n\t\t\t\tvalue,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tif (shouldRethrowTryError(error)) {\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\tconst stepFailure = readTryStepFailure(error);\n\t\t\tif (stepFailure) {\n\t\t\t\tconst failure: TryBlockFailure = {\n\t\t\t\t\tsource: \"step\",\n\t\t\t\t\tname: stepFailure.stepName,\n\t\t\t\t\terror: stepFailure.error,\n\t\t\t\t\tstep: stepFailure,\n\t\t\t\t};\n\t\t\t\tif (!shouldCatchTryBlockFailure(failure, config.catch)) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tok: false,\n\t\t\t\t\tfailure,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst operationFailure = readTryBlockFailure(error);\n\t\t\tif (operationFailure) {\n\t\t\t\tconst failure: TryBlockFailure = {\n\t\t\t\t\t...operationFailure,\n\t\t\t\t\terror: extractErrorInfo(error),\n\t\t\t\t};\n\t\t\t\tif (!shouldCatchTryBlockFailure(failure, config.catch)) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tok: false,\n\t\t\t\t\tfailure,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (error instanceof RollbackError) {\n\t\t\t\tconst failure: TryBlockFailure = {\n\t\t\t\t\tsource: \"block\",\n\t\t\t\t\tname: config.name,\n\t\t\t\t\terror: extractErrorInfo(error),\n\t\t\t\t};\n\t\t\t\tif (!shouldCatchTryBlockFailure(failure, config.catch)) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tok: false,\n\t\t\t\t\tfailure,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tprivate async executeStep<T>(config: StepConfig<T>): Promise<T> {\n\t\tthis.ensureRollbackCheckpoint(config);\n\t\tif (this.mode === \"rollback\") {\n\t\t\treturn await this.executeStepRollback(config);\n\t\t}\n\n\t\t// Check for duplicate name in current execution\n\t\tthis.checkDuplicateName(config.name);\n\n\t\tconst location = appendName(\n\t\t\tthis.storage,\n\t\t\tthis.currentLocation,\n\t\t\tconfig.name,\n\t\t);\n\t\tconst key = locationToKey(this.storage, location);\n\t\tconst existing = this.storage.history.entries.get(key);\n\n\t\t// Mark this entry as visited for validateComplete\n\t\tthis.markVisited(key);\n\n\t\tif (existing) {\n\t\t\tif (existing.kind.type !== \"step\") {\n\t\t\t\tthrow new HistoryDivergedError(\n\t\t\t\t\t`Expected step \"${config.name}\" at ${key}, found ${existing.kind.type}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst stepData = existing.kind.data;\n\n\t\t\tconst metadata = await loadMetadata(\n\t\t\t\tthis.storage,\n\t\t\t\tthis.driver,\n\t\t\t\texisting.id,\n\t\t\t);\n\n\t\t\t// Replay successful result (including void steps).\n\t\t\tif (\n\t\t\t\tmetadata.status === \"completed\" ||\n\t\t\t\tstepData.output !== undefined\n\t\t\t) {\n\t\t\t\treturn stepData.output as T;\n\t\t\t}\n\n\t\t\t// Check if we should retry\n\t\t\tconst maxRetries = config.maxRetries ?? DEFAULT_MAX_RETRIES;\n\n\t\t\tif (metadata.attempts > maxRetries) {\n\t\t\t\tconst lastError = metadata.error;\n\t\t\t\tconst exhaustedError = new StepExhaustedError(\n\t\t\t\t\tconfig.name,\n\t\t\t\t\tlastError,\n\t\t\t\t);\n\t\t\t\tattachTryStepFailure(\n\t\t\t\t\texhaustedError,\n\t\t\t\t\tgetTryStepFailureFromExhaustedError(\n\t\t\t\t\t\tconfig.name,\n\t\t\t\t\t\tmetadata.attempts,\n\t\t\t\t\t\texhaustedError,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tmarkErrorReported(exhaustedError);\n\t\t\t\tif (metadata.status !== \"exhausted\") {\n\t\t\t\t\tmetadata.status = \"exhausted\";\n\t\t\t\t\tmetadata.dirty = true;\n\t\t\t\t\tawait this.flushStorage();\n\t\t\t\t\tawait this.notifyStepError(\n\t\t\t\t\t\tconfig,\n\t\t\t\t\t\tmetadata.attempts,\n\t\t\t\t\t\texhaustedError,\n\t\t\t\t\t\t{ willRetry: false },\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tthrow exhaustedError;\n\t\t\t}\n\n\t\t\t// Calculate backoff and yield to scheduler\n\t\t\t// This allows the workflow to be evicted during backoff\n\t\t\tconst backoffDelay = calculateBackoff(\n\t\t\t\tmetadata.attempts,\n\t\t\t\tconfig.retryBackoffBase ?? DEFAULT_RETRY_BACKOFF_BASE,\n\t\t\t\tconfig.retryBackoffMax ?? DEFAULT_RETRY_BACKOFF_MAX,\n\t\t\t);\n\t\t\tconst retryAt = metadata.lastAttemptAt + backoffDelay;\n\t\t\tconst now = Date.now();\n\n\t\t\tif (now < retryAt) {\n\t\t\t\t// Yield to scheduler - will be woken up at retryAt\n\t\t\t\tthrow new SleepError(retryAt);\n\t\t\t}\n\t\t}\n\n\t\t// Execute the step\n\t\tconst entry =\n\t\t\texisting ?? createEntry(location, { type: \"step\", data: {} });\n\t\tif (!existing) {\n\t\t\t// New entry - register name\n\t\t\tthis.log(\"debug\", {\n\t\t\t\tmsg: \"executing new step\",\n\t\t\t\tstep: config.name,\n\t\t\t\tkey,\n\t\t\t});\n\t\t\tconst nameIndex = registerName(this.storage, config.name);\n\t\t\tentry.location = [...location];\n\t\t\tentry.location[entry.location.length - 1] = nameIndex;\n\t\t\tsetEntry(this.storage, location, entry);\n\t\t} else {\n\t\t\tthis.log(\"debug\", { msg: \"retrying step\", step: config.name, key });\n\t\t}\n\n\t\tconst metadata = getOrCreateMetadata(this.storage, entry.id);\n\t\tconst maxRetries = config.maxRetries ?? DEFAULT_MAX_RETRIES;\n\t\tconst retryBackoffBase =\n\t\t\tconfig.retryBackoffBase ?? DEFAULT_RETRY_BACKOFF_BASE;\n\t\tconst retryBackoffMax =\n\t\t\tconfig.retryBackoffMax ?? DEFAULT_RETRY_BACKOFF_MAX;\n\t\tmetadata.status = \"running\";\n\t\tmetadata.attempts++;\n\t\tmetadata.lastAttemptAt = Date.now();\n\t\tmetadata.dirty = true;\n\n\t\t// Get timeout configuration\n\t\tconst timeout = config.timeout ?? DEFAULT_STEP_TIMEOUT;\n\n\t\ttry {\n\t\t\t// Execute with timeout\n\t\t\tconst output = await this.executeWithTimeout(\n\t\t\t\tconfig.run(),\n\t\t\t\ttimeout,\n\t\t\t\tconfig.name,\n\t\t\t);\n\n\t\t\tif (entry.kind.type === \"step\") {\n\t\t\t\tentry.kind.data.output = output;\n\t\t\t}\n\t\t\tentry.dirty = true;\n\t\t\tmetadata.status = \"completed\";\n\t\t\tmetadata.error = undefined;\n\t\t\tmetadata.completedAt = Date.now();\n\n\t\t\t// Ephemeral steps don't trigger an immediate flush. This avoids the\n\t\t\t// synchronous write overhead for transient operations. Note that the\n\t\t\t// step's entry is still marked dirty and WILL be persisted on the\n\t\t\t// next flush from a non-ephemeral operation. The purpose of ephemeral\n\t\t\t// is to batch writes, not to avoid persistence entirely.\n\t\t\tif (!config.ephemeral) {\n\t\t\t\tthis.log(\"debug\", {\n\t\t\t\t\tmsg: \"flushing step\",\n\t\t\t\t\tstep: config.name,\n\t\t\t\t\tkey,\n\t\t\t\t});\n\t\t\t\tawait this.flushStorage();\n\t\t\t}\n\n\t\t\tthis.log(\"debug\", {\n\t\t\t\tmsg: \"step completed\",\n\t\t\t\tstep: config.name,\n\t\t\t\tkey,\n\t\t\t});\n\t\t\treturn output;\n\t\t} catch (error) {\n\t\t\tif (entry.kind.type === \"step\") {\n\t\t\t\tentry.kind.data.error = String(error);\n\t\t\t}\n\t\t\tentry.dirty = true;\n\n\t\t\t// Timeout errors are treated as critical by default. Steps opt\n\t\t\t// into retrying on timeout with retryOnTimeout: true.\n\t\t\tif (error instanceof StepTimeoutError && !config.retryOnTimeout) {\n\t\t\t\tmetadata.status = \"exhausted\";\n\t\t\t\tmetadata.error = String(error);\n\t\t\t\tawait this.notifyStepError(config, metadata.attempts, error, {\n\t\t\t\t\twillRetry: false,\n\t\t\t\t});\n\t\t\t\tthrow markErrorReported(\n\t\t\t\t\tattachTryStepFailure(new CriticalError(error.message), {\n\t\t\t\t\t\tkind: \"timeout\",\n\t\t\t\t\t\tstepName: config.name,\n\t\t\t\t\t\tattempts: metadata.attempts,\n\t\t\t\t\t\terror: extractErrorInfo(error),\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\terror instanceof CriticalError ||\n\t\t\t\terror instanceof RollbackError\n\t\t\t) {\n\t\t\t\tmetadata.status = \"exhausted\";\n\t\t\t\tmetadata.error = String(error);\n\t\t\t\tawait this.notifyStepError(config, metadata.attempts, error, {\n\t\t\t\t\twillRetry: false,\n\t\t\t\t});\n\t\t\t\tthrow markErrorReported(\n\t\t\t\t\tattachTryStepFailure(error, {\n\t\t\t\t\t\tkind:\n\t\t\t\t\t\t\terror instanceof RollbackError\n\t\t\t\t\t\t\t\t? \"rollback\"\n\t\t\t\t\t\t\t\t: \"critical\",\n\t\t\t\t\t\tstepName: config.name,\n\t\t\t\t\t\tattempts: metadata.attempts,\n\t\t\t\t\t\terror: extractErrorInfo(error),\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst willRetry = metadata.attempts <= maxRetries;\n\t\t\tmetadata.status = willRetry ? \"failed\" : \"exhausted\";\n\t\t\tmetadata.error = String(error);\n\n\t\t\tif (willRetry) {\n\t\t\t\tconst retryDelay = calculateBackoff(\n\t\t\t\t\tmetadata.attempts,\n\t\t\t\t\tretryBackoffBase,\n\t\t\t\t\tretryBackoffMax,\n\t\t\t\t);\n\t\t\t\tconst retryAt = metadata.lastAttemptAt + retryDelay;\n\t\t\t\tawait this.notifyStepError(config, metadata.attempts, error, {\n\t\t\t\t\twillRetry: true,\n\t\t\t\t\tretryDelay,\n\t\t\t\t\tretryAt,\n\t\t\t\t});\n\t\t\t\tthrow new StepFailedError(\n\t\t\t\t\tconfig.name,\n\t\t\t\t\terror,\n\t\t\t\t\tmetadata.attempts,\n\t\t\t\t\tretryAt,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst exhaustedError = markErrorReported(\n\t\t\t\tattachTryStepFailure(\n\t\t\t\t\tnew StepExhaustedError(config.name, String(error)),\n\t\t\t\t\t{\n\t\t\t\t\t\tkind:\n\t\t\t\t\t\t\terror instanceof StepTimeoutError\n\t\t\t\t\t\t\t\t? \"timeout\"\n\t\t\t\t\t\t\t\t: \"exhausted\",\n\t\t\t\t\t\tstepName: config.name,\n\t\t\t\t\t\tattempts: metadata.attempts,\n\t\t\t\t\t\terror: extractErrorInfo(error),\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t);\n\t\t\tawait this.notifyStepError(config, metadata.attempts, error, {\n\t\t\t\twillRetry: false,\n\t\t\t});\n\t\t\tthrow exhaustedError;\n\t\t}\n\t}\n\n\t/**\n\t * Execute a promise with timeout.\n\t *\n\t * Note: This does NOT cancel the underlying operation. JavaScript Promises\n\t * cannot be cancelled once started. When a timeout occurs:\n\t * - The step is rejected with StepTimeoutError. By default this is treated\n\t *   as a critical failure with no retry. Set retryOnTimeout: true on the\n\t *   step config to retry timeouts like any other error.\n\t * - The underlying async operation continues running in the background\n\t * - Any side effects from the operation may still occur\n\t *\n\t * For cancellable operations, pass ctx.abortSignal to APIs that support AbortSignal:\n\t *\n\t *     return fetch(url, { signal: ctx.abortSignal });\n\n\t *   });\n\t *\n\t * Or check ctx.isEvicted() periodically in long-running loops.\n\t */\n\tprivate async executeStepRollback<T>(config: StepConfig<T>): Promise<T> {\n\t\tthis.checkDuplicateName(config.name);\n\t\tthis.ensureRollbackCheckpoint(config);\n\n\t\tconst location = appendName(\n\t\t\tthis.storage,\n\t\t\tthis.currentLocation,\n\t\t\tconfig.name,\n\t\t);\n\t\tconst key = locationToKey(this.storage, location);\n\t\tconst existing = this.storage.history.entries.get(key);\n\n\t\tthis.markVisited(key);\n\n\t\tif (!existing || existing.kind.type !== \"step\") {\n\t\t\tthis.stopRollback();\n\t\t}\n\n\t\tconst metadata = await loadMetadata(\n\t\t\tthis.storage,\n\t\t\tthis.driver,\n\t\t\texisting.id,\n\t\t);\n\t\tif (metadata.status !== \"completed\") {\n\t\t\tthis.stopRollback();\n\t\t}\n\n\t\tconst output = existing.kind.data.output as T;\n\t\tthis.registerRollbackAction(config, existing.id, output, metadata);\n\n\t\treturn output;\n\t}\n\n\tprivate async executeWithTimeout<T>(\n\t\tpromise: Promise<T>,\n\t\ttimeoutMs: number,\n\t\tstepName: string,\n\t): Promise<T> {\n\t\tif (timeoutMs <= 0) {\n\t\t\treturn promise;\n\t\t}\n\n\t\tlet timeoutId: ReturnType<typeof setTimeout> | undefined;\n\t\tconst timeoutPromise = new Promise<never>((_, reject) => {\n\t\t\ttimeoutId = setTimeout(() => {\n\t\t\t\treject(new StepTimeoutError(stepName, timeoutMs));\n\t\t\t}, timeoutMs);\n\t\t});\n\n\t\ttry {\n\t\t\treturn await Promise.race([promise, timeoutPromise]);\n\t\t} finally {\n\t\t\tif (timeoutId !== undefined) {\n\t\t\t\tclearTimeout(timeoutId);\n\t\t\t}\n\t\t}\n\t}\n\n\t// === Loop ===\n\n\tasync loop<S, T>(\n\t\tnameOrConfig: string | LoopConfig<S, T>,\n\t\trun?: (\n\t\t\tctx: WorkflowContextInterface,\n\t\t) => LoopIterationResult<undefined, T>,\n\t): Promise<T> {\n\t\tthis.assertNotInProgress();\n\t\tthis.checkEvicted();\n\n\t\tconst config: LoopConfig<S, T> =\n\t\t\ttypeof nameOrConfig === \"string\"\n\t\t\t\t? { name: nameOrConfig, run: run as LoopConfig<S, T>[\"run\"] }\n\t\t\t\t: nameOrConfig;\n\n\t\tthis.entryInProgress = true;\n\t\ttry {\n\t\t\treturn await this.executeLoop(config);\n\t\t} finally {\n\t\t\tthis.entryInProgress = false;\n\t\t}\n\t}\n\n\tprivate async executeLoop<S, T>(config: LoopConfig<S, T>): Promise<T> {\n\t\t// Check for duplicate name in current execution\n\t\tthis.checkDuplicateName(config.name);\n\n\t\tconst location = appendName(\n\t\t\tthis.storage,\n\t\t\tthis.currentLocation,\n\t\t\tconfig.name,\n\t\t);\n\t\tconst key = locationToKey(this.storage, location);\n\t\tconst existing = this.storage.history.entries.get(key);\n\n\t\t// Mark this entry as visited for validateComplete\n\t\tthis.markVisited(key);\n\n\t\tlet entry: Entry;\n\t\tlet metadata: EntryMetadata | undefined;\n\t\tlet state: S;\n\t\tlet iteration: number;\n\t\tlet rollbackSingleIteration = false;\n\t\tlet rollbackIterationRan = false;\n\t\tlet rollbackOutput: T | undefined;\n\t\tconst rollbackMode = this.mode === \"rollback\";\n\n\t\tif (existing) {\n\t\t\tif (existing.kind.type !== \"loop\") {\n\t\t\t\tthrow new HistoryDivergedError(\n\t\t\t\t\t`Expected loop \"${config.name}\" at ${key}, found ${existing.kind.type}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst loopData = existing.kind.data;\n\t\t\tmetadata = await loadMetadata(\n\t\t\t\tthis.storage,\n\t\t\t\tthis.driver,\n\t\t\t\texisting.id,\n\t\t\t);\n\n\t\t\tif (rollbackMode) {\n\t\t\t\tif (loopData.output !== undefined) {\n\t\t\t\t\treturn loopData.output as T;\n\t\t\t\t}\n\t\t\t\trollbackSingleIteration = true;\n\t\t\t\trollbackIterationRan = false;\n\t\t\t\trollbackOutput = undefined;\n\t\t\t}\n\n\t\t\tif (metadata.status === \"completed\") {\n\t\t\t\treturn loopData.output as T;\n\t\t\t}\n\n\t\t\t// Loop already completed\n\t\t\tif (loopData.output !== undefined) {\n\t\t\t\treturn loopData.output as T;\n\t\t\t}\n\n\t\t\t// Resume from saved state\n\t\t\tentry = existing;\n\t\t\tstate = loopData.state as S;\n\t\t\titeration = loopData.iteration;\n\t\t\tif (rollbackMode) {\n\t\t\t\trollbackOutput = loopData.output as T | undefined;\n\t\t\t\trollbackIterationRan = rollbackOutput !== undefined;\n\t\t\t}\n\t\t} else {\n\t\t\tthis.stopRollbackIfIncomplete(true);\n\n\t\t\t// New loop\n\t\t\tstate = config.state as S;\n\t\t\titeration = 0;\n\t\t\tentry = createEntry(location, {\n\t\t\t\ttype: \"loop\",\n\t\t\t\tdata: { state, iteration },\n\t\t\t});\n\t\t\tsetEntry(this.storage, location, entry);\n\t\t\tmetadata = getOrCreateMetadata(this.storage, entry.id);\n\t\t}\n\n\t\tif (metadata) {\n\t\t\tmetadata.status = \"running\";\n\t\t\tmetadata.error = undefined;\n\t\t\tmetadata.dirty = true;\n\t\t}\n\n\t\tconst historyPruneInterval =\n\t\t\tconfig.historyPruneInterval ??\n\t\t\tconfig.commitInterval ??\n\t\t\tconfig.historyEvery ??\n\t\t\tDEFAULT_LOOP_HISTORY_PRUNE_INTERVAL;\n\t\tconst historySize =\n\t\t\tconfig.historySize ?? config.historyKeep ?? historyPruneInterval;\n\n\t\t// Track the last iteration we pruned up to so we only delete\n\t\t// newly-expired iterations instead of re-scanning from 0.\n\t\tlet lastPrunedUpTo = 0;\n\n\t\t// Deferred flush promise from the previous prune cycle. Awaited at the\n\t\t// start of the next iteration so the flush runs in parallel with user code.\n\t\tlet deferredFlush: Promise<void> | null = null;\n\n\t\t// Execute loop iterations\n\t\twhile (true) {\n\t\t\t// Await any deferred flush from the previous prune cycle\n\t\t\tif (deferredFlush) {\n\t\t\t\tawait deferredFlush;\n\t\t\t\tdeferredFlush = null;\n\t\t\t}\n\n\t\t\tif (rollbackMode && rollbackSingleIteration) {\n\t\t\t\tif (rollbackIterationRan) {\n\t\t\t\t\treturn rollbackOutput as T;\n\t\t\t\t}\n\t\t\t\tthis.stopRollbackIfIncomplete(true);\n\t\t\t}\n\t\t\tthis.checkEvicted();\n\n\t\t\t// Create branch for this iteration\n\t\t\tconst iterationLocation = appendLoopIteration(\n\t\t\t\tthis.storage,\n\t\t\t\tlocation,\n\t\t\t\tconfig.name,\n\t\t\t\titeration,\n\t\t\t);\n\t\t\tconst branchCtx = this.createBranch(iterationLocation);\n\n\t\t\t// Execute iteration\n\t\t\tconst iterationResult = await config.run(branchCtx, state);\n\t\t\tif (iterationResult === undefined && state !== undefined) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Loop \"${config.name}\" returned undefined for a stateful iteration. Return Loop.continue(state) or Loop.break(value).`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst result =\n\t\t\t\titerationResult === undefined\n\t\t\t\t\t? ({ continue: true, state } as LoopResult<S, T>)\n\t\t\t\t\t: iterationResult;\n\n\t\t\t// Validate branch completed cleanly\n\t\t\tbranchCtx.validateComplete();\n\n\t\t\tif (\"break\" in result && result.break) {\n\t\t\t\t// Loop complete\n\t\t\t\tif (entry.kind.type === \"loop\") {\n\t\t\t\t\tentry.kind.data.output = result.value;\n\t\t\t\t\tentry.kind.data.state = state;\n\t\t\t\t\tentry.kind.data.iteration = iteration;\n\t\t\t\t}\n\t\t\t\tentry.dirty = true;\n\t\t\t\tif (metadata) {\n\t\t\t\t\tmetadata.status = \"completed\";\n\t\t\t\t\tmetadata.completedAt = Date.now();\n\t\t\t\t\tmetadata.dirty = true;\n\t\t\t\t}\n\n\t\t\t\t// Collect pruning deletions and flush\n\t\t\t\tconst deletions = this.collectLoopPruning(\n\t\t\t\t\tlocation,\n\t\t\t\t\titeration + 1,\n\t\t\t\t\thistorySize,\n\t\t\t\t\tlastPrunedUpTo,\n\t\t\t\t);\n\t\t\t\tawait this.flushStorageWithDeletions(deletions);\n\n\t\t\t\tif (rollbackMode && rollbackSingleIteration) {\n\t\t\t\t\trollbackOutput = result.value;\n\t\t\t\t\trollbackIterationRan = true;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\treturn result.value;\n\t\t\t}\n\n\t\t\t// Continue with new state\n\t\t\tif (\"continue\" in result && result.continue) {\n\t\t\t\tstate = result.state;\n\t\t\t}\n\t\t\titeration++;\n\n\t\t\tif (!rollbackMode) {\n\t\t\t\tif (entry.kind.type === \"loop\") {\n\t\t\t\t\tentry.kind.data.state = state;\n\t\t\t\t\tentry.kind.data.iteration = iteration;\n\t\t\t\t}\n\t\t\t\tentry.dirty = true;\n\t\t\t}\n\n\t\t\t// Periodically defer the flush so the next iteration can overlap\n\t\t\t// with loop pruning and any pending dirty state writes.\n\t\t\tif (iteration % historyPruneInterval === 0) {\n\t\t\t\tconst deletions = this.collectLoopPruning(\n\t\t\t\t\tlocation,\n\t\t\t\t\titeration,\n\t\t\t\t\thistorySize,\n\t\t\t\t\tlastPrunedUpTo,\n\t\t\t\t);\n\t\t\t\tlastPrunedUpTo = Math.max(0, iteration - historySize);\n\n\t\t\t\t// Defer the flush to run in parallel with the next iteration\n\t\t\t\tdeferredFlush = this.flushStorageWithDeletions(deletions);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Collect pending deletions for loop history pruning.\n\t *\n\t * Only deletes iterations in the range [fromIteration, keepFrom) where\n\t * keepFrom = currentIteration - historySize. This avoids re-scanning\n\t * already-deleted iterations.\n\t */\n\tprivate collectLoopPruning(\n\t\tloopLocation: Location,\n\t\tcurrentIteration: number,\n\t\thistorySize: number,\n\t\tfromIteration: number,\n\t): PendingDeletions | undefined {\n\t\tif (currentIteration <= historySize) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst keepFrom = Math.max(0, currentIteration - historySize);\n\t\tif (fromIteration >= keepFrom) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst loopSegment = loopLocation[loopLocation.length - 1];\n\t\tif (typeof loopSegment !== \"number\") {\n\t\t\tthrow new Error(\"Expected loop location to end with a name index\");\n\t\t}\n\n\t\tconst range = buildLoopIterationRange(\n\t\t\tloopLocation,\n\t\t\tloopSegment,\n\t\t\tfromIteration,\n\t\t\tkeepFrom,\n\t\t);\n\t\tconst metadataKeys: Uint8Array[] = [];\n\n\t\tfor (const [key, entry] of this.storage.history.entries) {\n\t\t\tif (!isLocationPrefix(loopLocation, entry.location)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst iterationSegment = entry.location[loopLocation.length];\n\t\t\tif (\n\t\t\t\t!iterationSegment ||\n\t\t\t\ttypeof iterationSegment === \"number\" ||\n\t\t\t\titerationSegment.loop !== loopSegment ||\n\t\t\t\titerationSegment.iteration < fromIteration ||\n\t\t\t\titerationSegment.iteration >= keepFrom\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tmetadataKeys.push(buildEntryMetadataKey(entry.id));\n\t\t\tthis.storage.entryMetadata.delete(entry.id);\n\t\t\tthis.storage.history.entries.delete(key);\n\t\t}\n\n\t\treturn {\n\t\t\tprefixes: [],\n\t\t\tkeys: metadataKeys,\n\t\t\tranges: [range],\n\t\t};\n\t}\n\n\t/**\n\t * Flush storage with optional pending deletions so pruning\n\t * happens alongside the state write.\n\t */\n\tprivate async flushStorageWithDeletions(\n\t\tdeletions?: PendingDeletions,\n\t): Promise<void> {\n\t\tawait flush(this.storage, this.driver, this.historyNotifier, deletions);\n\t}\n\n\t// === Sleep ===\n\n\tasync sleep(name: string, durationMs: number): Promise<void> {\n\t\tconst deadline = Date.now() + durationMs;\n\t\treturn this.sleepUntil(name, deadline);\n\t}\n\n\tasync sleepUntil(name: string, timestampMs: number): Promise<void> {\n\t\tthis.assertNotInProgress();\n\t\tthis.checkEvicted();\n\n\t\tthis.entryInProgress = true;\n\t\ttry {\n\t\t\tawait this.executeSleep(name, timestampMs);\n\t\t} finally {\n\t\t\tthis.entryInProgress = false;\n\t\t}\n\t}\n\n\tprivate async executeSleep(name: string, deadline: number): Promise<void> {\n\t\t// Check for duplicate name in current execution\n\t\tthis.checkDuplicateName(name);\n\n\t\tconst location = appendName(this.storage, this.currentLocation, name);\n\t\tconst key = locationToKey(this.storage, location);\n\t\tconst existing = this.storage.history.entries.get(key);\n\n\t\t// Mark this entry as visited for validateComplete\n\t\tthis.markVisited(key);\n\n\t\tlet entry: Entry;\n\n\t\tif (existing) {\n\t\t\tif (existing.kind.type !== \"sleep\") {\n\t\t\t\tthrow new HistoryDivergedError(\n\t\t\t\t\t`Expected sleep \"${name}\" at ${key}, found ${existing.kind.type}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst sleepData = existing.kind.data;\n\n\t\t\tif (this.mode === \"rollback\") {\n\t\t\t\tthis.stopRollbackIfIncomplete(sleepData.state === \"pending\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Already completed or interrupted\n\t\t\tif (sleepData.state !== \"pending\") {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Use stored deadline\n\t\t\tdeadline = sleepData.deadline;\n\t\t\tentry = existing;\n\t\t} else {\n\t\t\tthis.stopRollbackIfIncomplete(true);\n\n\t\t\tentry = createEntry(location, {\n\t\t\t\ttype: \"sleep\",\n\t\t\t\tdata: { deadline, state: \"pending\" },\n\t\t\t});\n\t\t\tsetEntry(this.storage, location, entry);\n\t\t\tentry.dirty = true;\n\t\t\tawait this.flushStorage();\n\t\t}\n\n\t\tconst now = Date.now();\n\t\tconst remaining = deadline - now;\n\n\t\tif (remaining <= 0) {\n\t\t\t// Deadline passed\n\t\t\tif (entry.kind.type === \"sleep\") {\n\t\t\t\tentry.kind.data.state = \"completed\";\n\t\t\t}\n\t\t\tentry.dirty = true;\n\t\t\tawait this.flushStorage();\n\t\t\treturn;\n\t\t}\n\n\t\t// Short sleep: wait in memory\n\t\tif (remaining < this.driver.workerPollInterval) {\n\t\t\tawait this.sleepOrEvict(remaining);\n\n\t\t\tthis.checkEvicted();\n\n\t\t\tif (entry.kind.type === \"sleep\") {\n\t\t\t\tentry.kind.data.state = \"completed\";\n\t\t\t}\n\t\t\tentry.dirty = true;\n\t\t\tawait this.flushStorage();\n\t\t\treturn;\n\t\t}\n\n\t\t// Long sleep: yield to scheduler\n\t\tthrow new SleepError(deadline);\n\t}\n\n\t// === Rollback Checkpoint ===\n\n\tasync rollbackCheckpoint(name: string): Promise<void> {\n\t\tthis.assertNotInProgress();\n\t\tthis.checkEvicted();\n\n\t\tthis.entryInProgress = true;\n\t\ttry {\n\t\t\tawait this.executeRollbackCheckpoint(name);\n\t\t} finally {\n\t\t\tthis.entryInProgress = false;\n\t\t}\n\t}\n\n\tprivate async executeRollbackCheckpoint(name: string): Promise<void> {\n\t\tthis.checkDuplicateName(name);\n\n\t\tconst location = appendName(this.storage, this.currentLocation, name);\n\t\tconst key = locationToKey(this.storage, location);\n\t\tconst existing = this.storage.history.entries.get(key);\n\n\t\tthis.markVisited(key);\n\n\t\tif (existing) {\n\t\t\tif (existing.kind.type !== \"rollback_checkpoint\") {\n\t\t\t\tthrow new HistoryDivergedError(\n\t\t\t\t\t`Expected rollback checkpoint \"${name}\" at ${key}, found ${existing.kind.type}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.rollbackCheckpointSet = true;\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.mode === \"rollback\") {\n\t\t\tthrow new HistoryDivergedError(\n\t\t\t\t`Missing rollback checkpoint \"${name}\" at ${key}`,\n\t\t\t);\n\t\t}\n\n\t\tconst entry = createEntry(location, {\n\t\t\ttype: \"rollback_checkpoint\",\n\t\t\tdata: { name },\n\t\t});\n\t\tsetEntry(this.storage, location, entry);\n\t\tentry.dirty = true;\n\t\tawait this.flushStorage();\n\n\t\tthis.rollbackCheckpointSet = true;\n\t}\n\n\t// === Queue ===\n\n\tprivate async queueSend(name: string, body: unknown): Promise<void> {\n\t\tconst message: Message = {\n\t\t\tid: crypto.randomUUID(),\n\t\t\tname,\n\t\t\tdata: body,\n\t\t\tsentAt: Date.now(),\n\t\t};\n\t\tawait this.messageDriver.addMessage(message);\n\t}\n\n\tprivate async queueNext<T>(\n\t\tname: string,\n\t\topts?: WorkflowQueueNextOptions,\n\t): Promise<WorkflowQueueMessage<T>> {\n\t\tconst messages = await this.queueNextBatch<T>(name, {\n\t\t\t...(opts ?? {}),\n\t\t\tcount: 1,\n\t\t});\n\t\tconst message = messages[0];\n\t\tif (!message) {\n\t\t\tthrow new Error(\n\t\t\t\t`queue.next(\"${name}\") timed out before receiving a message. Use queue.nextBatch(...) for optional/time-limited reads.`,\n\t\t\t);\n\t\t}\n\t\treturn message;\n\t}\n\n\tprivate async queueNextBatch<T>(\n\t\tname: string,\n\t\topts?: WorkflowQueueNextBatchOptions,\n\t): Promise<Array<WorkflowQueueMessage<T>>> {\n\t\tthis.assertNotInProgress();\n\t\tthis.checkEvicted();\n\n\t\tthis.entryInProgress = true;\n\t\ttry {\n\t\t\treturn await this.executeQueueNextBatch<T>(name, opts);\n\t\t} finally {\n\t\t\tthis.entryInProgress = false;\n\t\t}\n\t}\n\n\tprivate async executeQueueNextBatch<T>(\n\t\tname: string,\n\t\topts?: WorkflowQueueNextBatchOptions,\n\t): Promise<Array<WorkflowQueueMessage<T>>> {\n\t\tif (this.pendingCompletableMessageIds.size > 0) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Previous completable queue message is not completed. Call `message.complete(...)` before receiving the next message.\",\n\t\t\t);\n\t\t}\n\n\t\tconst resolvedOpts = opts ?? {};\n\t\tconst messageNames = this.normalizeQueueNames(resolvedOpts.names);\n\t\tconst messageNameLabel = this.messageNamesLabel(messageNames);\n\t\tconst count = Math.max(1, resolvedOpts.count ?? 1);\n\t\tconst completable = resolvedOpts.completable === true;\n\n\t\tthis.checkDuplicateName(name);\n\n\t\tconst countLocation = appendName(\n\t\t\tthis.storage,\n\t\t\tthis.currentLocation,\n\t\t\t`${name}:count`,\n\t\t);\n\t\tconst countKey = locationToKey(this.storage, countLocation);\n\t\tconst existingCount = this.storage.history.entries.get(countKey);\n\t\tthis.markVisited(countKey);\n\t\tthis.stopRollbackIfMissing(existingCount);\n\n\t\tlet deadline: number | undefined;\n\t\tlet deadlineEntry: Entry | undefined;\n\t\tif (resolvedOpts.timeout !== undefined) {\n\t\t\tconst deadlineLocation = appendName(\n\t\t\t\tthis.storage,\n\t\t\t\tthis.currentLocation,\n\t\t\t\t`${name}:deadline`,\n\t\t\t);\n\t\t\tconst deadlineKey = locationToKey(this.storage, deadlineLocation);\n\t\t\tdeadlineEntry = this.storage.history.entries.get(deadlineKey);\n\t\t\tthis.markVisited(deadlineKey);\n\t\t\tthis.stopRollbackIfMissing(deadlineEntry);\n\n\t\t\tif (deadlineEntry && deadlineEntry.kind.type === \"sleep\") {\n\t\t\t\tdeadline = deadlineEntry.kind.data.deadline;\n\t\t\t} else {\n\t\t\t\tdeadline = Date.now() + resolvedOpts.timeout;\n\t\t\t\tconst created = createEntry(deadlineLocation, {\n\t\t\t\t\ttype: \"sleep\",\n\t\t\t\t\tdata: { deadline, state: \"pending\" },\n\t\t\t\t});\n\t\t\t\tsetEntry(this.storage, deadlineLocation, created);\n\t\t\t\tcreated.dirty = true;\n\t\t\t\tawait this.flushStorage();\n\t\t\t\tdeadlineEntry = created;\n\t\t\t}\n\t\t}\n\n\t\tif (existingCount && existingCount.kind.type === \"message\") {\n\t\t\tconst replayCount = existingCount.kind.data.data as number;\n\t\t\treturn await this.readReplayQueueMessages<T>(\n\t\t\t\tname,\n\t\t\t\treplayCount,\n\t\t\t\tcompletable,\n\t\t\t);\n\t\t}\n\n\t\tconst now = Date.now();\n\t\tif (deadline !== undefined && now >= deadline) {\n\t\t\tif (deadlineEntry && deadlineEntry.kind.type === \"sleep\") {\n\t\t\t\tdeadlineEntry.kind.data.state = \"completed\";\n\t\t\t\tdeadlineEntry.dirty = true;\n\t\t\t}\n\t\t\tawait this.recordQueueCountEntry(\n\t\t\t\tcountLocation,\n\t\t\t\t`${messageNameLabel}:count`,\n\t\t\t\t0,\n\t\t\t);\n\t\t\treturn [];\n\t\t}\n\n\t\tconst received = await this.receiveMessagesNow(\n\t\t\tmessageNames,\n\t\t\tcount,\n\t\t\tcompletable,\n\t\t);\n\t\tif (received.length > 0) {\n\t\t\tconst historyMessages = received.map((message) =>\n\t\t\t\tthis.toWorkflowQueueMessage<T>(message),\n\t\t\t);\n\t\t\tif (deadlineEntry && deadlineEntry.kind.type === \"sleep\") {\n\t\t\t\tdeadlineEntry.kind.data.state = \"interrupted\";\n\t\t\t\tdeadlineEntry.dirty = true;\n\t\t\t}\n\t\t\tawait this.recordQueueMessages(\n\t\t\t\tname,\n\t\t\t\tcountLocation,\n\t\t\t\tmessageNames,\n\t\t\t\thistoryMessages,\n\t\t\t);\n\t\t\tconst queueMessages = received.map((message, index) =>\n\t\t\t\tthis.createQueueMessage<T>(message, completable, {\n\t\t\t\t\thistoryLocation: appendName(\n\t\t\t\t\t\tthis.storage,\n\t\t\t\t\t\tthis.currentLocation,\n\t\t\t\t\t\t`${name}:${index}`,\n\t\t\t\t\t),\n\t\t\t\t}),\n\t\t\t);\n\t\t\treturn queueMessages;\n\t\t}\n\n\t\tif (deadline === undefined) {\n\t\t\tthrow new MessageWaitError(messageNames);\n\t\t}\n\t\tthrow new SleepError(deadline, messageNames);\n\t}\n\n\tprivate normalizeQueueNames(names?: readonly string[]): string[] {\n\t\tif (!names || names.length === 0) {\n\t\t\treturn [];\n\t\t}\n\t\tconst deduped: string[] = [];\n\t\tconst seen = new Set<string>();\n\t\tfor (const name of names) {\n\t\t\tif (seen.has(name)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tseen.add(name);\n\t\t\tdeduped.push(name);\n\t\t}\n\t\treturn deduped;\n\t}\n\n\tprivate messageNamesLabel(messageNames: string[]): string {\n\t\tif (messageNames.length === 0) {\n\t\t\treturn \"*\";\n\t\t}\n\t\treturn messageNames.length === 1\n\t\t\t? messageNames[0]\n\t\t\t: messageNames.join(\"|\");\n\t}\n\n\tprivate async receiveMessagesNow(\n\t\tmessageNames: string[],\n\t\tcount: number,\n\t\tcompletable: boolean,\n\t): Promise<Message[]> {\n\t\treturn await this.messageDriver.receiveMessages({\n\t\t\tnames: messageNames.length > 0 ? messageNames : undefined,\n\t\t\tcount,\n\t\t\tcompletable,\n\t\t});\n\t}\n\n\tprivate async recordQueueMessages<T>(\n\t\tname: string,\n\t\tcountLocation: Location,\n\t\tmessageNames: string[],\n\t\tmessages: Array<WorkflowQueueMessage<T>>,\n\t): Promise<void> {\n\t\tfor (let i = 0; i < messages.length; i++) {\n\t\t\tconst messageLocation = appendName(\n\t\t\t\tthis.storage,\n\t\t\t\tthis.currentLocation,\n\t\t\t\t`${name}:${i}`,\n\t\t\t);\n\t\t\tconst messageEntry = createEntry(messageLocation, {\n\t\t\t\ttype: \"message\",\n\t\t\t\tdata: {\n\t\t\t\t\tname: messages[i].name,\n\t\t\t\t\tdata: this.toHistoryQueueMessage(messages[i]),\n\t\t\t\t},\n\t\t\t});\n\t\t\tsetEntry(this.storage, messageLocation, messageEntry);\n\t\t\tthis.markVisited(locationToKey(this.storage, messageLocation));\n\t\t}\n\t\tawait this.recordQueueCountEntry(\n\t\t\tcountLocation,\n\t\t\t`${this.messageNamesLabel(messageNames)}:count`,\n\t\t\tmessages.length,\n\t\t);\n\t}\n\n\tprivate async recordQueueCountEntry(\n\t\tcountLocation: Location,\n\t\tcountLabel: string,\n\t\tcount: number,\n\t): Promise<void> {\n\t\tconst countEntry = createEntry(countLocation, {\n\t\t\ttype: \"message\",\n\t\t\tdata: {\n\t\t\t\tname: countLabel,\n\t\t\t\tdata: count,\n\t\t\t},\n\t\t});\n\t\tsetEntry(this.storage, countLocation, countEntry);\n\t\tawait this.flushStorage();\n\t}\n\n\tprivate async readReplayQueueMessages<T>(\n\t\tname: string,\n\t\tcount: number,\n\t\tcompletable: boolean,\n\t): Promise<Array<WorkflowQueueMessage<T>>> {\n\t\tconst results: Array<WorkflowQueueMessage<T>> = [];\n\t\tfor (let i = 0; i < count; i++) {\n\t\t\tconst messageLocation = appendName(\n\t\t\t\tthis.storage,\n\t\t\t\tthis.currentLocation,\n\t\t\t\t`${name}:${i}`,\n\t\t\t);\n\t\t\tconst messageKey = locationToKey(this.storage, messageLocation);\n\t\t\tthis.markVisited(messageKey);\n\t\t\tconst existingMessage =\n\t\t\t\tthis.storage.history.entries.get(messageKey);\n\t\t\tif (!existingMessage || existingMessage.kind.type !== \"message\") {\n\t\t\t\tthrow new HistoryDivergedError(\n\t\t\t\t\t`Expected queue message \"${name}:${i}\" in history`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst parsed = this.fromHistoryQueueMessage(\n\t\t\t\texistingMessage.kind.data.name,\n\t\t\t\texistingMessage.kind.data.data,\n\t\t\t);\n\t\t\tresults.push(\n\t\t\t\tthis.createQueueMessage<T>(parsed.message, completable, {\n\t\t\t\t\thistoryLocation: messageLocation,\n\t\t\t\t\tcompleted: parsed.completed,\n\t\t\t\t\treplay: true,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\treturn results;\n\t}\n\n\tprivate toWorkflowQueueMessage<T>(\n\t\tmessage: Message,\n\t): WorkflowQueueMessage<T> {\n\t\treturn {\n\t\t\tid: message.id,\n\t\t\tname: message.name,\n\t\t\tbody: message.data as T,\n\t\t\tcreatedAt: message.sentAt,\n\t\t};\n\t}\n\n\tprivate createQueueMessage<T>(\n\t\tmessage: Message,\n\t\tcompletable: boolean,\n\t\topts?: {\n\t\t\thistoryLocation?: Location;\n\t\t\tcompleted?: boolean;\n\t\t\treplay?: boolean;\n\t\t},\n\t): WorkflowQueueMessage<T> {\n\t\tconst queueMessage = this.toWorkflowQueueMessage<T>(message);\n\t\tif (!completable) {\n\t\t\treturn queueMessage;\n\t\t}\n\n\t\tif (opts?.replay && opts.completed) {\n\t\t\treturn {\n\t\t\t\t...queueMessage,\n\t\t\t\tcomplete: async () => {\n\t\t\t\t\t// No-op: this message was already completed in a prior run.\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\tconst messageId = message.id;\n\t\tthis.pendingCompletableMessageIds.add(messageId);\n\t\tlet completed = false;\n\n\t\treturn {\n\t\t\t...queueMessage,\n\t\t\tcomplete: async (response?: unknown) => {\n\t\t\t\tif (completed) {\n\t\t\t\t\tthrow new Error(\"Queue message already completed\");\n\t\t\t\t}\n\t\t\t\tcompleted = true;\n\t\t\t\ttry {\n\t\t\t\t\tawait this.completeMessage(message, response);\n\t\t\t\t\tawait this.markQueueMessageCompleted(opts?.historyLocation);\n\t\t\t\t\tthis.pendingCompletableMessageIds.delete(messageId);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tcompleted = false;\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t},\n\t\t};\n\t}\n\n\tprivate async markQueueMessageCompleted(\n\t\thistoryLocation: Location | undefined,\n\t): Promise<void> {\n\t\tif (!historyLocation) {\n\t\t\treturn;\n\t\t}\n\t\tconst key = locationToKey(this.storage, historyLocation);\n\t\tconst entry = this.storage.history.entries.get(key);\n\t\tif (!entry || entry.kind.type !== \"message\") {\n\t\t\treturn;\n\t\t}\n\t\tconst parsed = this.fromHistoryQueueMessage(\n\t\t\tentry.kind.data.name,\n\t\t\tentry.kind.data.data,\n\t\t);\n\t\tentry.kind.data.data = this.toHistoryQueueMessage(\n\t\t\tthis.toWorkflowQueueMessage(parsed.message),\n\t\t\ttrue,\n\t\t);\n\t\tentry.dirty = true;\n\t\tawait this.flushStorage();\n\t}\n\n\tprivate async completeMessage(\n\t\tmessage: Message,\n\t\tresponse?: unknown,\n\t): Promise<void> {\n\t\tif (message.complete) {\n\t\t\tawait message.complete(response);\n\t\t\treturn;\n\t\t}\n\t\tawait this.messageDriver.completeMessage(message.id, response);\n\t}\n\n\tprivate toHistoryQueueMessage(\n\t\tmessage: WorkflowQueueMessage<unknown>,\n\t\tcompleted = false,\n\t): unknown {\n\t\treturn {\n\t\t\t[QUEUE_HISTORY_MESSAGE_MARKER]: 1,\n\t\t\tid: message.id,\n\t\t\tname: message.name,\n\t\t\tbody: message.body,\n\t\t\tcreatedAt: message.createdAt,\n\t\t\tcompleted,\n\t\t};\n\t}\n\n\tprivate fromHistoryQueueMessage(\n\t\tname: string,\n\t\tvalue: unknown,\n\t): { message: Message; completed: boolean } {\n\t\tif (\n\t\t\ttypeof value === \"object\" &&\n\t\t\tvalue !== null &&\n\t\t\t(value as Record<string, unknown>)[QUEUE_HISTORY_MESSAGE_MARKER] ===\n\t\t\t\t1\n\t\t) {\n\t\t\tconst serialized = value as Record<string, unknown>;\n\t\t\tconst id = typeof serialized.id === \"string\" ? serialized.id : \"\";\n\t\t\tconst serializedName =\n\t\t\t\ttypeof serialized.name === \"string\" ? serialized.name : name;\n\t\t\tconst createdAt =\n\t\t\t\ttypeof serialized.createdAt === \"number\"\n\t\t\t\t\t? serialized.createdAt\n\t\t\t\t\t: 0;\n\t\t\tconst completed =\n\t\t\t\ttypeof serialized.completed === \"boolean\"\n\t\t\t\t\t? serialized.completed\n\t\t\t\t\t: false;\n\t\t\treturn {\n\t\t\t\tmessage: {\n\t\t\t\t\tid,\n\t\t\t\t\tname: serializedName,\n\t\t\t\t\tdata: serialized.body,\n\t\t\t\t\tsentAt: createdAt,\n\t\t\t\t},\n\t\t\t\tcompleted,\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tmessage: {\n\t\t\t\tid: \"\",\n\t\t\t\tname,\n\t\t\t\tdata: value,\n\t\t\t\tsentAt: 0,\n\t\t\t},\n\t\t\tcompleted: false,\n\t\t};\n\t}\n\n\t// === Join ===\n\n\tasync join<T extends Record<string, BranchConfig<unknown>>>(\n\t\tname: string,\n\t\tbranches: T,\n\t): Promise<{ [K in keyof T]: BranchOutput<T[K]> }> {\n\t\tthis.assertNotInProgress();\n\t\tthis.checkEvicted();\n\n\t\tthis.entryInProgress = true;\n\t\ttry {\n\t\t\treturn await this.executeJoin(name, branches);\n\t\t} finally {\n\t\t\tthis.entryInProgress = false;\n\t\t}\n\t}\n\n\tprivate async executeJoin<T extends Record<string, BranchConfig<unknown>>>(\n\t\tname: string,\n\t\tbranches: T,\n\t): Promise<{ [K in keyof T]: BranchOutput<T[K]> }> {\n\t\t// Check for duplicate name in current execution\n\t\tthis.checkDuplicateName(name);\n\n\t\tconst location = appendName(this.storage, this.currentLocation, name);\n\t\tconst key = locationToKey(this.storage, location);\n\t\tconst existing = this.storage.history.entries.get(key);\n\n\t\t// Mark this entry as visited for validateComplete\n\t\tthis.markVisited(key);\n\n\t\tthis.stopRollbackIfMissing(existing);\n\n\t\tlet entry: Entry;\n\n\t\tif (existing) {\n\t\t\tif (existing.kind.type !== \"join\") {\n\t\t\t\tthrow new HistoryDivergedError(\n\t\t\t\t\t`Expected join \"${name}\" at ${key}, found ${existing.kind.type}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tentry = existing;\n\t\t} else {\n\t\t\tentry = createEntry(location, {\n\t\t\t\ttype: \"join\",\n\t\t\t\tdata: {\n\t\t\t\t\tbranches: Object.fromEntries(\n\t\t\t\t\t\tObject.keys(branches).map((k) => [\n\t\t\t\t\t\t\tk,\n\t\t\t\t\t\t\t{ status: \"pending\" as const },\n\t\t\t\t\t\t]),\n\t\t\t\t\t),\n\t\t\t\t},\n\t\t\t});\n\t\t\tsetEntry(this.storage, location, entry);\n\t\t\tentry.dirty = true;\n\t\t\t// Flush immediately to persist entry before branches execute\n\t\t\tawait this.flushStorage();\n\t\t}\n\n\t\tif (entry.kind.type !== \"join\") {\n\t\t\tthrow new HistoryDivergedError(\"Entry type mismatch\");\n\t\t}\n\n\t\tthis.stopRollbackIfIncomplete(\n\t\t\tObject.values(entry.kind.data.branches).some(\n\t\t\t\t(branch) => branch.status !== \"completed\",\n\t\t\t),\n\t\t);\n\n\t\tconst joinData = entry.kind.data;\n\t\tconst results: Record<string, unknown> = {};\n\t\tconst errors: Record<string, Error> = {};\n\t\tlet schedulerYieldState: SchedulerYieldState | undefined;\n\t\tlet propagatedError: Error | undefined;\n\n\t\tfor (const [branchName, branchStatus] of Object.entries(\n\t\t\tjoinData.branches,\n\t\t)) {\n\t\t\tif (branchStatus.status === \"completed\") {\n\t\t\t\tresults[branchName] = branchStatus.output;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (branchStatus.status === \"failed\") {\n\t\t\t\terrors[branchName] = new Error(\n\t\t\t\t\tbranchStatus.error ?? \"branch failed\",\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Execute all branches in parallel\n\t\tconst branchPromises = Object.entries(branches).map(\n\t\t\tasync ([branchName, config]) => {\n\t\t\t\tconst branchStatus = joinData.branches[branchName];\n\t\t\t\tif (!branchStatus) {\n\t\t\t\t\tthrow new HistoryDivergedError(\n\t\t\t\t\t\t`Expected join branch \"${branchName}\" in \"${name}\"`,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t// Already completed\n\t\t\t\tif (branchStatus.status === \"completed\") {\n\t\t\t\t\tresults[branchName] = branchStatus.output;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Already failed\n\t\t\t\tif (branchStatus.status === \"failed\") {\n\t\t\t\t\terrors[branchName] = new Error(branchStatus.error);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Execute branch\n\t\t\t\tconst branchLocation = appendName(\n\t\t\t\t\tthis.storage,\n\t\t\t\t\tlocation,\n\t\t\t\t\tbranchName,\n\t\t\t\t);\n\t\t\t\tconst branchCtx = this.createBranch(branchLocation);\n\n\t\t\t\tbranchStatus.status = \"running\";\n\t\t\t\tbranchStatus.error = undefined;\n\t\t\t\tentry.dirty = true;\n\n\t\t\t\ttry {\n\t\t\t\t\tconst output = await config.run(branchCtx);\n\t\t\t\t\tbranchCtx.validateComplete();\n\n\t\t\t\t\tbranchStatus.status = \"completed\";\n\t\t\t\t\tbranchStatus.output = output;\n\t\t\t\t\tbranchStatus.error = undefined;\n\t\t\t\t\tresults[branchName] = output;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (\n\t\t\t\t\t\terror instanceof SleepError ||\n\t\t\t\t\t\terror instanceof MessageWaitError ||\n\t\t\t\t\t\terror instanceof StepFailedError\n\t\t\t\t\t) {\n\t\t\t\t\t\tschedulerYieldState = mergeSchedulerYield(\n\t\t\t\t\t\t\tschedulerYieldState,\n\t\t\t\t\t\t\terror,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbranchStatus.status = \"running\";\n\t\t\t\t\t\tbranchStatus.error = undefined;\n\t\t\t\t\t\tentry.dirty = true;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (\n\t\t\t\t\t\terror instanceof EvictedError ||\n\t\t\t\t\t\terror instanceof HistoryDivergedError ||\n\t\t\t\t\t\terror instanceof EntryInProgressError ||\n\t\t\t\t\t\terror instanceof RollbackCheckpointError ||\n\t\t\t\t\t\terror instanceof RollbackStopError\n\t\t\t\t\t) {\n\t\t\t\t\t\tpropagatedError = selectControlFlowError(\n\t\t\t\t\t\t\tpropagatedError,\n\t\t\t\t\t\t\terror,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbranchStatus.status = \"running\";\n\t\t\t\t\t\tbranchStatus.error = undefined;\n\t\t\t\t\t\tentry.dirty = true;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tbranchStatus.status = \"failed\";\n\t\t\t\t\tbranchStatus.output = undefined;\n\t\t\t\t\tbranchStatus.error = String(error);\n\t\t\t\t\terrors[branchName] = error as Error;\n\t\t\t\t}\n\n\t\t\t\tentry.dirty = true;\n\t\t\t},\n\t\t);\n\n\t\t// Wait for ALL branches (no short-circuit on error)\n\t\tawait Promise.allSettled(branchPromises);\n\t\tawait this.flushStorage();\n\n\t\tif (propagatedError) {\n\t\t\tthrow propagatedError;\n\t\t}\n\n\t\tif (\n\t\t\tObject.values(joinData.branches).some(\n\t\t\t\t(branch) =>\n\t\t\t\t\tbranch.status === \"pending\" || branch.status === \"running\",\n\t\t\t)\n\t\t) {\n\t\t\tif (!schedulerYieldState) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Join \"${name}\" has pending branches without a scheduler yield`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow buildSchedulerYieldError(schedulerYieldState);\n\t\t}\n\n\t\t// Throw if any branches failed\n\t\tif (Object.keys(errors).length > 0) {\n\t\t\tthrow attachTryBlockFailure(new JoinError(errors), {\n\t\t\t\tsource: \"join\",\n\t\t\t\tname,\n\t\t\t});\n\t\t}\n\n\t\treturn results as { [K in keyof T]: BranchOutput<T[K]> };\n\t}\n\n\t// === Race ===\n\n\tasync race<T>(\n\t\tname: string,\n\t\tbranches: Array<{\n\t\t\tname: string;\n\t\t\trun: (ctx: WorkflowContextInterface) => Promise<T>;\n\t\t}>,\n\t): Promise<{ winner: string; value: T }> {\n\t\tthis.assertNotInProgress();\n\t\tthis.checkEvicted();\n\n\t\tthis.entryInProgress = true;\n\t\ttry {\n\t\t\treturn await this.executeRace(name, branches);\n\t\t} finally {\n\t\t\tthis.entryInProgress = false;\n\t\t}\n\t}\n\n\tprivate async executeRace<T>(\n\t\tname: string,\n\t\tbranches: Array<{\n\t\t\tname: string;\n\t\t\trun: (ctx: WorkflowContextInterface) => Promise<T>;\n\t\t}>,\n\t): Promise<{ winner: string; value: T }> {\n\t\t// Check for duplicate name in current execution\n\t\tthis.checkDuplicateName(name);\n\n\t\tconst location = appendName(this.storage, this.currentLocation, name);\n\t\tconst key = locationToKey(this.storage, location);\n\t\tconst existing = this.storage.history.entries.get(key);\n\n\t\t// Mark this entry as visited for validateComplete\n\t\tthis.markVisited(key);\n\n\t\tthis.stopRollbackIfMissing(existing);\n\n\t\tlet entry: Entry;\n\n\t\tif (existing) {\n\t\t\tif (existing.kind.type !== \"race\") {\n\t\t\t\tthrow new HistoryDivergedError(\n\t\t\t\t\t`Expected race \"${name}\" at ${key}, found ${existing.kind.type}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tentry = existing;\n\n\t\t\t// Check if we already have a winner\n\t\t\tconst raceKind = existing.kind;\n\t\t\tif (raceKind.data.winner !== null) {\n\t\t\t\tconst winnerStatus =\n\t\t\t\t\traceKind.data.branches[raceKind.data.winner];\n\t\t\t\treturn {\n\t\t\t\t\twinner: raceKind.data.winner,\n\t\t\t\t\tvalue: winnerStatus.output as T,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tthis.stopRollbackIfIncomplete(true);\n\t\t} else {\n\t\t\tentry = createEntry(location, {\n\t\t\t\ttype: \"race\",\n\t\t\t\tdata: {\n\t\t\t\t\twinner: null,\n\t\t\t\t\tbranches: Object.fromEntries(\n\t\t\t\t\t\tbranches.map((b) => [\n\t\t\t\t\t\t\tb.name,\n\t\t\t\t\t\t\t{ status: \"pending\" as const },\n\t\t\t\t\t\t]),\n\t\t\t\t\t),\n\t\t\t\t},\n\t\t\t});\n\t\t\tsetEntry(this.storage, location, entry);\n\t\t\tentry.dirty = true;\n\t\t\t// Flush immediately to persist entry before branches execute\n\t\t\tawait this.flushStorage();\n\t\t}\n\n\t\tif (entry.kind.type !== \"race\") {\n\t\t\tthrow new HistoryDivergedError(\"Entry type mismatch\");\n\t\t}\n\n\t\tconst raceData = entry.kind.data;\n\n\t\t// Create abort controller for cancellation\n\t\tconst raceAbortController = new AbortController();\n\n\t\t// Track all branch promises to wait for cleanup\n\t\tconst branchPromises: Promise<void>[] = [];\n\n\t\t// Track winner info\n\t\tlet winnerName: string | null = null;\n\t\tlet winnerValue: T | undefined;\n\t\tlet hasWinner = false;\n\t\tconst errors: Record<string, Error> = {};\n\t\tconst lateErrors: Array<{ name: string; error: string }> = [];\n\t\tlet schedulerYieldState: SchedulerYieldState | undefined;\n\t\tlet propagatedError: Error | undefined;\n\n\t\t// Check for replay winners first\n\t\tfor (const branch of branches) {\n\t\t\tconst branchStatus = raceData.branches[branch.name];\n\t\t\tif (!branchStatus) {\n\t\t\t\tthrow new HistoryDivergedError(\n\t\t\t\t\t`Expected race branch \"${branch.name}\" in \"${name}\"`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (\n\t\t\t\tbranchStatus.status !== \"pending\" &&\n\t\t\t\tbranchStatus.status !== \"running\"\n\t\t\t) {\n\t\t\t\tif (branchStatus.status === \"failed\") {\n\t\t\t\t\terrors[branch.name] = new Error(\n\t\t\t\t\t\tbranchStatus.error ?? \"branch failed\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (branchStatus.status === \"completed\" && !hasWinner) {\n\t\t\t\t\thasWinner = true;\n\t\t\t\t\twinnerName = branch.name;\n\t\t\t\t\twinnerValue = branchStatus.output as T;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// If we found a replay winner, return immediately\n\t\tif (hasWinner && winnerName !== null) {\n\t\t\treturn { winner: winnerName, value: winnerValue as T };\n\t\t}\n\n\t\t// Execute branches that need to run\n\t\tfor (const branch of branches) {\n\t\t\tconst branchStatus = raceData.branches[branch.name];\n\t\t\tif (!branchStatus) {\n\t\t\t\tthrow new HistoryDivergedError(\n\t\t\t\t\t`Expected race branch \"${branch.name}\" in \"${name}\"`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Skip already completed/cancelled\n\t\t\tif (\n\t\t\t\tbranchStatus.status !== \"pending\" &&\n\t\t\t\tbranchStatus.status !== \"running\"\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst branchLocation = appendName(\n\t\t\t\tthis.storage,\n\t\t\t\tlocation,\n\t\t\t\tbranch.name,\n\t\t\t);\n\t\t\tconst branchCtx = this.createBranch(\n\t\t\t\tbranchLocation,\n\t\t\t\traceAbortController,\n\t\t\t);\n\n\t\t\tbranchStatus.status = \"running\";\n\t\t\tbranchStatus.error = undefined;\n\t\t\tentry.dirty = true;\n\n\t\t\tconst branchPromise = branch.run(branchCtx).then(\n\t\t\t\tasync (output) => {\n\t\t\t\t\tif (hasWinner) {\n\t\t\t\t\t\t// This branch completed after a winner was determined\n\t\t\t\t\t\t// Still record the completion for observability\n\t\t\t\t\t\tbranchStatus.status = \"completed\";\n\t\t\t\t\t\tbranchStatus.output = output;\n\t\t\t\t\t\tbranchStatus.error = undefined;\n\t\t\t\t\t\tentry.dirty = true;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (propagatedError) {\n\t\t\t\t\t\tbranchStatus.status = \"completed\";\n\t\t\t\t\t\tbranchStatus.output = output;\n\t\t\t\t\t\tbranchStatus.error = undefined;\n\t\t\t\t\t\tentry.dirty = true;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\thasWinner = true;\n\t\t\t\t\twinnerName = branch.name;\n\t\t\t\t\twinnerValue = output;\n\n\t\t\t\t\tbranchCtx.validateComplete();\n\n\t\t\t\t\tbranchStatus.status = \"completed\";\n\t\t\t\t\tbranchStatus.output = output;\n\t\t\t\t\tbranchStatus.error = undefined;\n\t\t\t\t\traceData.winner = branch.name;\n\t\t\t\t\tentry.dirty = true;\n\n\t\t\t\t\t// Cancel other branches\n\t\t\t\t\traceAbortController.abort();\n\t\t\t\t},\n\t\t\t\t(error) => {\n\t\t\t\t\tif (hasWinner) {\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\terror instanceof CancelledError ||\n\t\t\t\t\t\t\terror instanceof EvictedError\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tbranchStatus.status = \"cancelled\";\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tlateErrors.push({\n\t\t\t\t\t\t\t\tname: branch.name,\n\t\t\t\t\t\t\t\terror: String(error),\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tentry.dirty = true;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (\n\t\t\t\t\t\terror instanceof SleepError ||\n\t\t\t\t\t\terror instanceof MessageWaitError ||\n\t\t\t\t\t\terror instanceof StepFailedError\n\t\t\t\t\t) {\n\t\t\t\t\t\tschedulerYieldState = mergeSchedulerYield(\n\t\t\t\t\t\t\tschedulerYieldState,\n\t\t\t\t\t\t\terror,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbranchStatus.status = \"running\";\n\t\t\t\t\t\tbranchStatus.error = undefined;\n\t\t\t\t\t\tentry.dirty = true;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (\n\t\t\t\t\t\terror instanceof EvictedError ||\n\t\t\t\t\t\terror instanceof HistoryDivergedError ||\n\t\t\t\t\t\terror instanceof EntryInProgressError ||\n\t\t\t\t\t\terror instanceof RollbackCheckpointError ||\n\t\t\t\t\t\terror instanceof RollbackStopError\n\t\t\t\t\t) {\n\t\t\t\t\t\tpropagatedError = selectControlFlowError(\n\t\t\t\t\t\t\tpropagatedError,\n\t\t\t\t\t\t\terror,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbranchStatus.status = \"running\";\n\t\t\t\t\t\tbranchStatus.error = undefined;\n\t\t\t\t\t\tentry.dirty = true;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (error instanceof CancelledError) {\n\t\t\t\t\t\tbranchStatus.status = \"cancelled\";\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbranchStatus.status = \"failed\";\n\t\t\t\t\t\tbranchStatus.output = undefined;\n\t\t\t\t\t\tbranchStatus.error = String(error);\n\t\t\t\t\t\terrors[branch.name] = error as Error;\n\t\t\t\t\t}\n\t\t\t\t\tentry.dirty = true;\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tbranchPromises.push(branchPromise);\n\t\t}\n\n\t\t// Wait for all branches to complete or be cancelled\n\t\tawait Promise.allSettled(branchPromises);\n\n\t\tif (propagatedError) {\n\t\t\tawait this.flushStorage();\n\t\t\tthrow propagatedError;\n\t\t}\n\n\t\tif (\n\t\t\t!hasWinner &&\n\t\t\tObject.values(raceData.branches).some(\n\t\t\t\t(branch) =>\n\t\t\t\t\tbranch.status === \"pending\" || branch.status === \"running\",\n\t\t\t)\n\t\t) {\n\t\t\tawait this.flushStorage();\n\t\t\tif (!schedulerYieldState) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Race \"${name}\" has pending branches without a scheduler yield`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow buildSchedulerYieldError(schedulerYieldState);\n\t\t}\n\n\t\t// Clean up entries from non-winning branches\n\t\tif (hasWinner && winnerName !== null) {\n\t\t\tfor (const branch of branches) {\n\t\t\t\tif (branch.name !== winnerName) {\n\t\t\t\t\tconst branchLocation = appendName(\n\t\t\t\t\t\tthis.storage,\n\t\t\t\t\t\tlocation,\n\t\t\t\t\t\tbranch.name,\n\t\t\t\t\t);\n\t\t\t\t\tawait deleteEntriesWithPrefix(\n\t\t\t\t\t\tthis.storage,\n\t\t\t\t\t\tthis.driver,\n\t\t\t\t\t\tbranchLocation,\n\t\t\t\t\t\tthis.historyNotifier,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Flush final state\n\t\tawait this.flushStorage();\n\n\t\t// Log late errors if any (these occurred after a winner was determined)\n\t\tif (lateErrors.length > 0) {\n\t\t\tconsole.warn(\n\t\t\t\t`Race \"${name}\" had ${lateErrors.length} branch(es) fail after winner was determined:`,\n\t\t\t\tlateErrors,\n\t\t\t);\n\t\t}\n\n\t\t// Return result or throw error\n\t\tif (hasWinner && winnerName !== null) {\n\t\t\treturn { winner: winnerName, value: winnerValue as T };\n\t\t}\n\n\t\t// All branches failed\n\t\tthrow attachTryBlockFailure(\n\t\t\tnew RaceError(\n\t\t\t\t\"All branches failed\",\n\t\t\t\tObject.entries(errors).map(([branchName, error]) => ({\n\t\t\t\t\tname: branchName,\n\t\t\t\t\terror: String(error),\n\t\t\t\t})),\n\t\t\t),\n\t\t\t{\n\t\t\t\tsource: \"race\",\n\t\t\t\tname,\n\t\t\t},\n\t\t);\n\t}\n\n\t// === Removed ===\n\n\tasync removed(name: string, originalType: EntryKindType): Promise<void> {\n\t\tthis.assertNotInProgress();\n\t\tthis.checkEvicted();\n\n\t\tthis.entryInProgress = true;\n\t\ttry {\n\t\t\tawait this.executeRemoved(name, originalType);\n\t\t} finally {\n\t\t\tthis.entryInProgress = false;\n\t\t}\n\t}\n\n\tprivate async executeRemoved(\n\t\tname: string,\n\t\toriginalType: EntryKindType,\n\t): Promise<void> {\n\t\t// Check for duplicate name in current execution\n\t\tthis.checkDuplicateName(name);\n\n\t\tconst location = appendName(this.storage, this.currentLocation, name);\n\t\tconst key = locationToKey(this.storage, location);\n\t\tconst existing = this.storage.history.entries.get(key);\n\n\t\t// Mark this entry as visited for validateComplete\n\t\tthis.markVisited(key);\n\n\t\tthis.stopRollbackIfMissing(existing);\n\n\t\tif (existing) {\n\t\t\t// Validate the existing entry matches what we expect\n\t\t\tif (\n\t\t\t\texisting.kind.type !== \"removed\" &&\n\t\t\t\texisting.kind.type !== originalType\n\t\t\t) {\n\t\t\t\tthrow new HistoryDivergedError(\n\t\t\t\t\t`Expected ${originalType} or removed at ${key}, found ${existing.kind.type}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// If it's not already marked as removed, we just skip it\n\t\t\treturn;\n\t\t}\n\n\t\t// Create a removed entry placeholder\n\t\tconst entry = createEntry(location, {\n\t\t\ttype: \"removed\",\n\t\t\tdata: { originalType, originalName: name },\n\t\t});\n\t\tsetEntry(this.storage, location, entry);\n\t\tawait this.flushStorage();\n\t}\n\n\t// === Version ===\n\n\tasync getVersion(name: string, latest: number): Promise<number> {\n\t\tthis.assertNotInProgress();\n\t\tthis.checkEvicted();\n\n\t\tthis.entryInProgress = true;\n\t\ttry {\n\t\t\treturn await this.executeGetVersion(name, latest);\n\t\t} finally {\n\t\t\tthis.entryInProgress = false;\n\t\t}\n\t}\n\n\tprivate async executeGetVersion(\n\t\tname: string,\n\t\tlatest: number,\n\t): Promise<number> {\n\t\tif (!Number.isInteger(latest) || latest < 1) {\n\t\t\tthrow new Error(\n\t\t\t\t`getVersion(\"${name}\", ${latest}): latest must be an integer >= 1`,\n\t\t\t);\n\t\t}\n\n\t\t// Check for duplicate name in current execution\n\t\tthis.checkDuplicateName(name);\n\n\t\tconst location = appendName(this.storage, this.currentLocation, name);\n\t\tconst key = locationToKey(this.storage, location);\n\t\tconst existing = this.storage.history.entries.get(key);\n\n\t\t// Mark this entry as visited for validateComplete\n\t\tthis.markVisited(key);\n\n\t\tthis.stopRollbackIfMissing(existing);\n\n\t\tif (existing) {\n\t\t\tif (existing.kind.type !== \"version_check\") {\n\t\t\t\tthrow new HistoryDivergedError(\n\t\t\t\t\t`Expected version_check at ${key}, found ${existing.kind.type}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\t// Pure replay: this instance is already pinned at this location.\n\t\t\treturn existing.kind.data.resolved;\n\t\t}\n\n\t\t// No recorded version at this location. Decide whether this instance\n\t\t// already executed past this point under older code (old in-flight) or\n\t\t// is reaching it fresh at the live frontier.\n\t\t//\n\t\t// The discriminator is \"is there any unvisited history entry under the\n\t\t// current scope?\". Entries created earlier in this same run are already\n\t\t// marked visited, so the only unvisited entries under the scope are\n\t\t// leftovers from a prior run, which proves this scope already executed\n\t\t// under code that predates this gate. Such instances resolve to the\n\t\t// implicit floor version 1 (old branch); fresh instances resolve to\n\t\t// `latest`.\n\t\tconst resolved = this.hasUnvisitedUnderCurrentScope(key) ? 1 : latest;\n\n\t\tconst entry = createEntry(location, {\n\t\t\ttype: \"version_check\",\n\t\t\tdata: { resolved, latest },\n\t\t});\n\t\tsetEntry(this.storage, location, entry);\n\t\tawait this.flushStorage();\n\n\t\treturn resolved;\n\t}\n\n\t/**\n\t * Returns true if any history entry under the current location scope\n\t * (other than `excludeKey`) has not yet been visited this run. Used by\n\t * getVersion to detect an old in-flight instance whose scope was already\n\t * executed by code that predates a version gate.\n\t */\n\tprivate hasUnvisitedUnderCurrentScope(excludeKey: string): boolean {\n\t\tconst prefix = locationToKey(this.storage, this.currentLocation);\n\n\t\tfor (const key of this.storage.history.entries.keys()) {\n\t\t\tif (key === excludeKey) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst isUnderPrefix =\n\t\t\t\tprefix === \"\"\n\t\t\t\t\t? true\n\t\t\t\t\t: key.startsWith(`${prefix}/`) || key === prefix;\n\t\t\tif (isUnderPrefix && !this.visitedKeys.has(key)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n}\n","/**\n * Sleep for a given number of milliseconds.\n */\nexport function sleep(ms: number): Promise<void> {\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nconst TIMEOUT_MAX = 2147483647;\n\nexport type LongTimeoutHandle = { abort: () => void };\n\nexport function setLongTimeout(\n\tlistener: () => void,\n\tafter: number,\n): LongTimeoutHandle {\n\tlet timeout: ReturnType<typeof setTimeout> | undefined;\n\n\tfunction start(remaining: number) {\n\t\tif (remaining <= TIMEOUT_MAX) {\n\t\t\ttimeout = setTimeout(listener, remaining);\n\t\t} else {\n\t\t\ttimeout = setTimeout(() => {\n\t\t\t\tstart(remaining - TIMEOUT_MAX);\n\t\t\t}, TIMEOUT_MAX);\n\t\t}\n\t}\n\n\tstart(after);\n\n\treturn {\n\t\tabort: () => {\n\t\t\tif (timeout !== undefined) clearTimeout(timeout);\n\t\t},\n\t};\n}\n\n/**\n * Safely parse JSON with a meaningful error message.\n */\nexport function safeJsonParse<T>(value: string, context: string): T {\n\ttry {\n\t\treturn JSON.parse(value) as T;\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Failed to parse ${context}: ${error instanceof Error ? error.message : String(error)}`,\n\t\t);\n\t}\n}\n","import type { Logger } from \"pino\";\n\n// Types\n\n// Context\nexport {\n\tDEFAULT_LOOP_HISTORY_PRUNE_INTERVAL,\n\tDEFAULT_MAX_RETRIES,\n\tDEFAULT_RETRY_BACKOFF_BASE,\n\tDEFAULT_RETRY_BACKOFF_MAX,\n\tDEFAULT_STEP_TIMEOUT,\n\tWorkflowContextImpl,\n} from \"./context.js\";\n// Driver\nexport type { EngineDriver, KVEntry, KVWrite } from \"./driver.js\";\nexport { extractErrorInfo } from \"./error-utils.js\";\n// Errors\nexport {\n\tCancelledError,\n\tCriticalError,\n\tEntryInProgressError,\n\tEvictedError,\n\tHistoryDivergedError,\n\tJoinError,\n\tMessageWaitError,\n\tRaceError,\n\tRollbackCheckpointError,\n\tRollbackError,\n\tSleepError,\n\tStepExhaustedError,\n\tStepFailedError,\n} from \"./errors.js\";\n\n// Location utilities\nexport {\n\tappendLoopIteration,\n\tappendName,\n\temptyLocation,\n\tisLocationPrefix,\n\tisLoopIterationMarker,\n\tlocationsEqual,\n\tlocationToKey,\n\tparentLocation,\n\tregisterName,\n\tresolveName,\n} from \"./location.js\";\n\n// Storage utilities\nexport {\n\tcreateEntry,\n\tcreateHistorySnapshot,\n\tcreateStorage,\n\tdeleteEntriesWithPrefix,\n\tflush,\n\tgenerateId,\n\tgetEntry,\n\tgetOrCreateMetadata,\n\tloadMetadata,\n\tloadStorage,\n\tsetEntry,\n} from \"./storage.js\";\nexport type {\n\tBranchConfig,\n\tBranchOutput,\n\tBranchStatus,\n\tBranchStatusType,\n\tEntry,\n\tEntryKind,\n\tEntryKindType,\n\tEntryMetadata,\n\tEntryStatus,\n\tHistory,\n\tJoinEntry,\n\tLocation,\n\tLoopConfig,\n\tLoopEntry,\n\tLoopIterationMarker,\n\tLoopResult,\n\tMessage,\n\tMessageEntry,\n\tNameIndex,\n\tPathSegment,\n\tRaceEntry,\n\tRemovedEntry,\n\tRollbackCheckpointEntry,\n\tRollbackContextInterface,\n\tRunWorkflowOptions,\n\tSleepEntry,\n\tSleepState,\n\tStepConfig,\n\tStepEntry,\n\tStorage,\n\tTryBlockCatchKind,\n\tTryBlockConfig,\n\tTryBlockFailure,\n\tTryBlockResult,\n\tTryStepCatchKind,\n\tTryStepConfig,\n\tTryStepFailure,\n\tTryStepResult,\n\tWorkflowContextInterface,\n\tWorkflowEntryMetadataSnapshot,\n\tWorkflowError,\n\tWorkflowErrorEvent,\n\tWorkflowErrorHandler,\n\tWorkflowFunction,\n\tWorkflowHandle,\n\tWorkflowHistoryEntry,\n\tWorkflowHistorySnapshot,\n\tWorkflowMessageDriver,\n\tWorkflowQueue,\n\tWorkflowQueueMessage,\n\tWorkflowQueueNextBatchOptions,\n\tWorkflowQueueNextOptions,\n\tWorkflowResult,\n\tWorkflowRollbackErrorEvent,\n\tWorkflowRunErrorEvent,\n\tWorkflowRunMode,\n\tWorkflowState,\n\tWorkflowStepErrorEvent,\n} from \"./types.js\";\n\n// Loop result helpers\nexport const Loop = {\n\tcontinue: <S>(state: S): { continue: true; state: S } => ({\n\t\tcontinue: true,\n\t\tstate,\n\t}),\n\tbreak: <T>(value: T): { break: true; value: T } => ({\n\t\tbreak: true,\n\t\tvalue,\n\t}),\n};\n\nimport {\n\tdeserializeEntryMetadata,\n\tdeserializeWorkflowInput,\n\tdeserializeWorkflowOutput,\n\tdeserializeWorkflowState,\n\tserializeEntryMetadata,\n\tserializeWorkflowInput,\n\tserializeWorkflowState,\n} from \"../schemas/serde.js\";\nimport { type RollbackAction, WorkflowContextImpl } from \"./context.js\";\n// Main workflow runner\nimport type { EngineDriver } from \"./driver.js\";\nimport {\n\textractErrorInfo,\n\tgetErrorEventTag,\n\tisErrorReported,\n\tmarkErrorReported,\n} from \"./error-utils.js\";\nimport {\n\tCriticalError,\n\tEvictedError,\n\tMessageWaitError,\n\tRollbackCheckpointError,\n\tRollbackError,\n\tRollbackStopError,\n\tSleepError,\n\tStepExhaustedError,\n\tStepFailedError,\n} from \"./errors.js\";\nimport {\n\tbuildEntryMetadataKey,\n\tbuildEntryMetadataPrefix,\n\tbuildHistoryKey,\n\tbuildWorkflowErrorKey,\n\tbuildWorkflowInputKey,\n\tbuildWorkflowOutputKey,\n\tbuildWorkflowStateKey,\n} from \"./keys.js\";\nimport { isLocationPrefix } from \"./location.js\";\nimport {\n\tcreateHistorySnapshot,\n\tflush,\n\tgenerateId,\n\tloadMetadata,\n\tloadStorage,\n} from \"./storage.js\";\nimport type {\n\tEntry,\n\tEntryMetadata,\n\tRollbackContextInterface,\n\tRunWorkflowOptions,\n\tStorage,\n\tWorkflowErrorEvent,\n\tWorkflowFunction,\n\tWorkflowHandle,\n\tWorkflowHistorySnapshot,\n\tWorkflowMessageDriver,\n\tWorkflowResult,\n\tWorkflowRunMode,\n\tWorkflowState,\n} from \"./types.js\";\nimport { setLongTimeout } from \"./utils.js\";\n\n/**\n * Run a workflow and return a handle for managing it.\n *\n * The workflow starts executing immediately. Use the returned handle to:\n * - `handle.result` - Await workflow completion (or yield in `yield` mode)\n * - `handle.message()` - Send messages to the workflow\n * - `handle.wake()` - Wake the workflow early\n * - `handle.evict()` - Request graceful shutdown\n * - `handle.getOutput()` / `handle.getState()` - Query status\n */\ninterface LiveRuntime {\n\tsleepWaiter?: () => void;\n\tisSleeping: boolean;\n}\n\ntype HistoryNotifier = (() => void) | undefined;\n\ntype ReplayEntryRecord = {\n\tkey: string;\n\tentry: Entry;\n\tmetadata: EntryMetadata;\n};\n\nfunction createLiveRuntime(): LiveRuntime {\n\treturn {\n\t\tisSleeping: false,\n\t};\n}\n\nfunction createEvictionWait(signal: AbortSignal): {\n\tpromise: Promise<never>;\n\tcleanup: () => void;\n} {\n\tif (signal.aborted) {\n\t\treturn {\n\t\t\tpromise: Promise.reject(new EvictedError()),\n\t\t\tcleanup: () => {},\n\t\t};\n\t}\n\n\tlet onAbort: (() => void) | undefined;\n\tconst promise = new Promise<never>((_, reject) => {\n\t\tonAbort = () => {\n\t\t\treject(new EvictedError());\n\t\t};\n\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t});\n\n\treturn {\n\t\tpromise,\n\t\tcleanup: () => {\n\t\t\tif (onAbort) {\n\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t}\n\t\t},\n\t};\n}\n\nfunction createRollbackContext(\n\tworkflowId: string,\n\tabortController: AbortController,\n): RollbackContextInterface {\n\treturn {\n\t\tworkflowId,\n\t\tabortSignal: abortController.signal,\n\t\tisEvicted: () => abortController.signal.aborted,\n\t};\n}\n\nasync function awaitWithEviction<T>(\n\tpromise: Promise<T>,\n\tabortSignal: AbortSignal,\n): Promise<T> {\n\tconst { promise: evictionPromise, cleanup } =\n\t\tcreateEvictionWait(abortSignal);\n\ttry {\n\t\treturn await Promise.race([promise, evictionPromise]);\n\t} finally {\n\t\tcleanup();\n\t}\n}\n\nasync function executeRollback<TInput, TOutput>(\n\tworkflowId: string,\n\tworkflowFn: WorkflowFunction<TInput, TOutput>,\n\tinput: TInput,\n\tdriver: EngineDriver,\n\tmessageDriver: WorkflowMessageDriver,\n\tabortController: AbortController,\n\tstorage: Storage,\n\thistoryNotifier?: HistoryNotifier,\n\tonError?: RunWorkflowOptions[\"onError\"],\n\tlogger?: Logger,\n): Promise<void> {\n\tconst rollbackActions: RollbackAction[] = [];\n\tconst ctx = new WorkflowContextImpl(\n\t\tworkflowId,\n\t\tstorage,\n\t\tdriver,\n\t\tmessageDriver,\n\t\tundefined,\n\t\tabortController,\n\t\t\"rollback\",\n\t\trollbackActions,\n\t\tfalse,\n\t\thistoryNotifier,\n\t\tonError,\n\t\tlogger,\n\t);\n\n\ttry {\n\t\tawait workflowFn(ctx, input);\n\t} catch (error) {\n\t\tif (error instanceof EvictedError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof RollbackStopError) {\n\t\t\t// Stop replay once we hit incomplete history during rollback.\n\t\t} else {\n\t\t\t// Ignore workflow errors during rollback replay.\n\t\t}\n\t}\n\n\tif (rollbackActions.length === 0) {\n\t\treturn;\n\t}\n\n\tconst rollbackContext = createRollbackContext(workflowId, abortController);\n\n\tfor (let i = rollbackActions.length - 1; i >= 0; i--) {\n\t\tif (abortController.signal.aborted) {\n\t\t\tthrow new EvictedError();\n\t\t}\n\n\t\tconst action = rollbackActions[i];\n\t\tconst metadata = await loadMetadata(storage, driver, action.entryId);\n\t\tif (metadata.rollbackCompletedAt !== undefined) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tlet rollbackEvent: WorkflowErrorEvent | undefined;\n\t\ttry {\n\t\t\tawait awaitWithEviction(\n\t\t\t\taction.rollback(rollbackContext, action.output),\n\t\t\t\tabortController.signal,\n\t\t\t);\n\t\t\tmetadata.rollbackCompletedAt = Date.now();\n\t\t\tmetadata.rollbackError = undefined;\n\t\t} catch (error) {\n\t\t\tif (error instanceof EvictedError) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tmetadata.rollbackError =\n\t\t\t\terror instanceof Error ? error.message : String(error);\n\t\t\tif (onError) {\n\t\t\t\trollbackEvent = {\n\t\t\t\t\trollback: {\n\t\t\t\t\t\tworkflowId,\n\t\t\t\t\t\tstepName: action.name,\n\t\t\t\t\t\terror: extractErrorInfo(error),\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (error instanceof Error) {\n\t\t\t\tmarkErrorReported(error);\n\t\t\t}\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tmetadata.dirty = true;\n\t\t\tawait flush(storage, driver, historyNotifier);\n\t\t\tif (rollbackEvent && onError) {\n\t\t\t\tawait notifyError(onError, logger, rollbackEvent);\n\t\t\t}\n\t\t}\n\t}\n}\n\nasync function notifyError(\n\tonError: NonNullable<RunWorkflowOptions[\"onError\"]>,\n\tlogger: Logger | undefined,\n\tevent: WorkflowErrorEvent,\n): Promise<void> {\n\ttry {\n\t\tawait onError(event);\n\t} catch (error) {\n\t\tlogger?.warn({\n\t\t\tmsg: \"workflow error hook failed\",\n\t\t\thookEventType: getErrorEventTag(event),\n\t\t\terror: extractErrorInfo(error),\n\t\t});\n\t}\n}\n\nasync function setSleepState<TOutput>(\n\tstorage: Storage,\n\tdriver: EngineDriver,\n\tworkflowId: string,\n\tdeadline: number,\n\tmessageNames?: string[],\n\thistoryNotifier?: HistoryNotifier,\n): Promise<WorkflowResult<TOutput>> {\n\tstorage.state = \"sleeping\";\n\tawait flush(storage, driver, historyNotifier);\n\tawait driver.setAlarm(workflowId, deadline);\n\n\treturn {\n\t\tstate: \"sleeping\",\n\t\tsleepUntil: deadline,\n\t\twaitingForMessages: messageNames,\n\t};\n}\n\nasync function setMessageWaitState<TOutput>(\n\tstorage: Storage,\n\tdriver: EngineDriver,\n\tmessageNames: string[],\n\thistoryNotifier?: HistoryNotifier,\n): Promise<WorkflowResult<TOutput>> {\n\tstorage.state = \"sleeping\";\n\tawait flush(storage, driver, historyNotifier);\n\n\treturn { state: \"sleeping\", waitingForMessages: messageNames };\n}\n\nasync function setEvictedState<TOutput>(\n\tstorage: Storage,\n\tdriver: EngineDriver,\n\thistoryNotifier?: HistoryNotifier,\n): Promise<WorkflowResult<TOutput>> {\n\tawait flush(storage, driver, historyNotifier);\n\treturn { state: storage.state };\n}\n\nasync function setRetryState<TOutput>(\n\tstorage: Storage,\n\tdriver: EngineDriver,\n\tworkflowId: string,\n\tretryAt: number,\n\thistoryNotifier?: HistoryNotifier,\n): Promise<WorkflowResult<TOutput>> {\n\tstorage.state = \"sleeping\";\n\tawait flush(storage, driver, historyNotifier);\n\n\tawait driver.setAlarm(workflowId, retryAt);\n\n\treturn { state: \"sleeping\", sleepUntil: retryAt };\n}\n\nasync function setFailedState(\n\tstorage: Storage,\n\tdriver: EngineDriver,\n\terror: unknown,\n\thistoryNotifier?: HistoryNotifier,\n): Promise<void> {\n\tstorage.state = \"failed\";\n\tstorage.error = extractErrorInfo(error);\n\tawait flush(storage, driver, historyNotifier);\n}\n\nasync function waitForSleep(\n\truntime: LiveRuntime,\n\tdeadline: number,\n\tabortSignal: AbortSignal,\n): Promise<void> {\n\twhile (true) {\n\t\tconst remaining = deadline - Date.now();\n\t\tif (remaining <= 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet timeoutHandle: ReturnType<typeof setLongTimeout> | undefined;\n\t\tconst timeoutPromise = new Promise<void>((resolve) => {\n\t\t\ttimeoutHandle = setLongTimeout(resolve, remaining);\n\t\t});\n\n\t\tconst wakePromise = new Promise<void>((resolve) => {\n\t\t\truntime.sleepWaiter = resolve;\n\t\t});\n\t\truntime.isSleeping = true;\n\n\t\ttry {\n\t\t\tawait awaitWithEviction(\n\t\t\t\tPromise.race([timeoutPromise, wakePromise]),\n\t\t\t\tabortSignal,\n\t\t\t);\n\t\t} finally {\n\t\t\truntime.isSleeping = false;\n\t\t\truntime.sleepWaiter = undefined;\n\t\t\ttimeoutHandle?.abort();\n\t\t}\n\n\t\tif (abortSignal.aborted) {\n\t\t\tthrow new EvictedError();\n\t\t}\n\n\t\tif (Date.now() >= deadline) {\n\t\t\treturn;\n\t\t}\n\t}\n}\n\nasync function executeLiveWorkflow<TInput, TOutput>(\n\tworkflowId: string,\n\tworkflowFn: WorkflowFunction<TInput, TOutput>,\n\tinput: TInput,\n\tdriver: EngineDriver,\n\tmessageDriver: WorkflowMessageDriver,\n\tabortController: AbortController,\n\truntime: LiveRuntime,\n\tonHistoryUpdated?: (history: WorkflowHistorySnapshot) => void,\n\tonError?: RunWorkflowOptions[\"onError\"],\n\tlogger?: Logger,\n): Promise<WorkflowResult<TOutput>> {\n\tlet lastResult: WorkflowResult<TOutput> | undefined;\n\n\twhile (true) {\n\t\tconst result = await executeWorkflow(\n\t\t\tworkflowId,\n\t\t\tworkflowFn,\n\t\t\tinput,\n\t\t\tdriver,\n\t\t\tmessageDriver,\n\t\t\tabortController,\n\t\t\tonHistoryUpdated,\n\t\t\tonError,\n\t\t\tlogger,\n\t\t);\n\t\tlastResult = result;\n\n\t\tif (result.state !== \"sleeping\") {\n\t\t\treturn result;\n\t\t}\n\n\t\tconst hasMessages = result.waitingForMessages !== undefined;\n\t\tconst hasDeadline = result.sleepUntil !== undefined;\n\n\t\tif (hasMessages && hasDeadline) {\n\t\t\t// Wait for EITHER a message OR the deadline (for queue.next timeout).\n\t\t\t// Scope both waiters to a per-iteration controller chained to the run\n\t\t\t// signal so that whichever loses the race is cancelled immediately.\n\t\t\t// Otherwise the loser (a message waiter or an armed sleep timer) stays\n\t\t\t// registered on the long-lived run signal and leaks once per cycle.\n\t\t\tconst iterationAbort = new AbortController();\n\t\t\tconst onRunAbort = () => iterationAbort.abort();\n\t\t\tif (abortController.signal.aborted) {\n\t\t\t\titerationAbort.abort();\n\t\t\t} else {\n\t\t\t\tabortController.signal.addEventListener(\"abort\", onRunAbort, {\n\t\t\t\t\tonce: true,\n\t\t\t\t});\n\t\t\t}\n\t\t\tconst messagePromise = awaitWithEviction(\n\t\t\t\tdriver.waitForMessages(\n\t\t\t\t\tresult.waitingForMessages!,\n\t\t\t\t\titerationAbort.signal,\n\t\t\t\t),\n\t\t\t\titerationAbort.signal,\n\t\t\t);\n\t\t\tconst sleepPromise = waitForSleep(\n\t\t\t\truntime,\n\t\t\t\tresult.sleepUntil!,\n\t\t\t\titerationAbort.signal,\n\t\t\t);\n\t\t\t// Swallow the loser's rejection once it is aborted below so it does\n\t\t\t// not surface as an unhandled rejection.\n\t\t\tmessagePromise.catch(() => {});\n\t\t\tsleepPromise.catch(() => {});\n\t\t\ttry {\n\t\t\t\tawait Promise.race([messagePromise, sleepPromise]);\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof EvictedError) {\n\t\t\t\t\treturn lastResult;\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t} finally {\n\t\t\t\titerationAbort.abort();\n\t\t\t\tabortController.signal.removeEventListener(\"abort\", onRunAbort);\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (hasMessages) {\n\t\t\ttry {\n\t\t\t\tawait awaitWithEviction(\n\t\t\t\t\tdriver.waitForMessages(\n\t\t\t\t\t\tresult.waitingForMessages!,\n\t\t\t\t\t\tabortController.signal,\n\t\t\t\t\t),\n\t\t\t\t\tabortController.signal,\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof EvictedError) {\n\t\t\t\t\treturn lastResult;\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (hasDeadline) {\n\t\t\ttry {\n\t\t\t\tawait waitForSleep(\n\t\t\t\t\truntime,\n\t\t\t\t\tresult.sleepUntil!,\n\t\t\t\t\tabortController.signal,\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof EvictedError) {\n\t\t\t\t\treturn lastResult;\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\treturn result;\n\t}\n}\n\nexport function runWorkflow<TInput, TOutput>(\n\tworkflowId: string,\n\tworkflowFn: WorkflowFunction<TInput, TOutput>,\n\tinput: TInput,\n\tdriver: EngineDriver,\n\toptions: RunWorkflowOptions = {},\n): WorkflowHandle<TOutput> {\n\tconst messageDriver = driver.messageDriver;\n\tconst abortController = new AbortController();\n\tconst mode: WorkflowRunMode = options.mode ?? \"yield\";\n\tconst liveRuntime = mode === \"live\" ? createLiveRuntime() : undefined;\n\n\tconst logger = options.logger;\n\n\tconst resultPromise =\n\t\tmode === \"live\" && liveRuntime\n\t\t\t? executeLiveWorkflow(\n\t\t\t\t\tworkflowId,\n\t\t\t\t\tworkflowFn,\n\t\t\t\t\tinput,\n\t\t\t\t\tdriver,\n\t\t\t\t\tmessageDriver,\n\t\t\t\t\tabortController,\n\t\t\t\t\tliveRuntime,\n\t\t\t\t\toptions.onHistoryUpdated,\n\t\t\t\t\toptions.onError,\n\t\t\t\t\tlogger,\n\t\t\t\t)\n\t\t\t: executeWorkflow(\n\t\t\t\t\tworkflowId,\n\t\t\t\t\tworkflowFn,\n\t\t\t\t\tinput,\n\t\t\t\t\tdriver,\n\t\t\t\t\tmessageDriver,\n\t\t\t\t\tabortController,\n\t\t\t\t\toptions.onHistoryUpdated,\n\t\t\t\t\toptions.onError,\n\t\t\t\t\tlogger,\n\t\t\t\t);\n\n\treturn {\n\t\tworkflowId,\n\t\tresult: resultPromise,\n\n\t\tasync message(name: string, data: unknown): Promise<void> {\n\t\t\tconst messageId = generateId();\n\t\t\tawait messageDriver.addMessage({\n\t\t\t\tid: messageId,\n\t\t\t\tname,\n\t\t\t\tdata,\n\t\t\t\tsentAt: Date.now(),\n\t\t\t});\n\t\t},\n\n\t\tasync wake(): Promise<void> {\n\t\t\tif (liveRuntime) {\n\t\t\t\tif (liveRuntime.isSleeping && liveRuntime.sleepWaiter) {\n\t\t\t\t\tliveRuntime.sleepWaiter();\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait driver.setAlarm(workflowId, Date.now());\n\t\t},\n\n\t\tasync recover(): Promise<void> {\n\t\t\tconst stateValue = await driver.get(buildWorkflowStateKey());\n\t\t\tconst state = stateValue\n\t\t\t\t? deserializeWorkflowState(stateValue)\n\t\t\t\t: \"pending\";\n\n\t\t\tif (state !== \"failed\") {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst metadataEntries = await driver.list(\n\t\t\t\tbuildEntryMetadataPrefix(),\n\t\t\t);\n\t\t\tconst writes: { key: Uint8Array; value: Uint8Array }[] = [];\n\n\t\t\tfor (const entry of metadataEntries) {\n\t\t\t\tconst metadata = deserializeEntryMetadata(entry.value);\n\t\t\t\tif (\n\t\t\t\t\tmetadata.status !== \"failed\" &&\n\t\t\t\t\tmetadata.status !== \"exhausted\"\n\t\t\t\t) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tmetadata.status = \"pending\";\n\t\t\t\tmetadata.attempts = 0;\n\t\t\t\tmetadata.lastAttemptAt = 0;\n\t\t\t\tmetadata.error = undefined;\n\t\t\t\tmetadata.dirty = false;\n\n\t\t\t\twrites.push({\n\t\t\t\t\tkey: entry.key,\n\t\t\t\t\tvalue: serializeEntryMetadata(metadata),\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (writes.length > 0) {\n\t\t\t\tawait driver.batch(writes);\n\t\t\t}\n\n\t\t\tawait driver.delete(buildWorkflowErrorKey());\n\t\t\tawait driver.set(\n\t\t\t\tbuildWorkflowStateKey(),\n\t\t\t\tserializeWorkflowState(\"sleeping\"),\n\t\t\t);\n\n\t\t\tif (liveRuntime) {\n\t\t\t\tif (liveRuntime.isSleeping && liveRuntime.sleepWaiter) {\n\t\t\t\t\tliveRuntime.sleepWaiter();\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tawait driver.setAlarm(workflowId, Date.now());\n\t\t},\n\n\t\tevict(): void {\n\t\t\tabortController.abort(new EvictedError());\n\t\t},\n\n\t\tasync cancel(): Promise<void> {\n\t\t\tabortController.abort(new EvictedError());\n\n\t\t\tawait driver.set(\n\t\t\t\tbuildWorkflowStateKey(),\n\t\t\t\tserializeWorkflowState(\"cancelled\"),\n\t\t\t);\n\n\t\t\tawait driver.clearAlarm(workflowId);\n\t\t},\n\n\t\tasync getOutput(): Promise<TOutput | undefined> {\n\t\t\tconst value = await driver.get(buildWorkflowOutputKey());\n\t\t\tif (!value) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\treturn deserializeWorkflowOutput<TOutput>(value);\n\t\t},\n\n\t\tasync getState(): Promise<WorkflowState> {\n\t\t\tconst value = await driver.get(buildWorkflowStateKey());\n\t\t\tif (!value) {\n\t\t\t\treturn \"pending\";\n\t\t\t}\n\t\t\treturn deserializeWorkflowState(value);\n\t\t},\n\t};\n}\n\n/**\n * Remove a step and every later workflow entry, then schedule the workflow to\n * start again immediately. Omitting `entryId` replays the workflow from the\n * beginning.\n */\nexport async function replayWorkflowFromStep(\n\tworkflowId: string,\n\tdriver: EngineDriver,\n\tentryId?: string,\n\toptions?: {\n\t\tscheduleAlarm?: boolean;\n\t},\n): Promise<WorkflowHistorySnapshot> {\n\tconst storage = await loadStorage(driver);\n\tconst entries = await Promise.all(\n\t\tArray.from(storage.history.entries.entries()).map(\n\t\t\tasync ([key, entry]) => ({\n\t\t\t\tkey,\n\t\t\t\tentry,\n\t\t\t\tmetadata: await loadMetadata(storage, driver, entry.id),\n\t\t\t}),\n\t\t),\n\t);\n\tconst ordered = [...entries].sort((a, b) => {\n\t\tif (a.metadata.createdAt !== b.metadata.createdAt) {\n\t\t\treturn a.metadata.createdAt - b.metadata.createdAt;\n\t\t}\n\t\treturn a.key.localeCompare(b.key);\n\t});\n\n\tlet entriesToDelete = ordered;\n\tif (entryId !== undefined) {\n\t\tconst target = entries.find(({ entry }) => entry.id === entryId);\n\t\tif (!target) {\n\t\t\tthrow new Error(`Workflow step not found: ${entryId}`);\n\t\t}\n\t\tif (target.entry.kind.type !== \"step\") {\n\t\t\tthrow new Error(\"Workflow replay target must be a step\");\n\t\t}\n\n\t\tconst replayBoundary = findReplayBoundaryEntry(entries, target);\n\t\tconst targetIndex = ordered.findIndex(\n\t\t\t({ entry }) => entry.id === replayBoundary.entry.id,\n\t\t);\n\t\tentriesToDelete = ordered.slice(targetIndex);\n\t}\n\n\tconst entryIdsToDelete = new Set(\n\t\tentriesToDelete.map(({ entry }) => entry.id),\n\t);\n\tif (\n\t\tentries.some(\n\t\t\t({ entry, metadata }) =>\n\t\t\t\tmetadata.status === \"running\" &&\n\t\t\t\t!entryIdsToDelete.has(entry.id),\n\t\t)\n\t) {\n\t\tthrow new Error(\n\t\t\t\"Cannot replay a workflow while a step is currently running\",\n\t\t);\n\t}\n\n\tawait Promise.all(\n\t\tentriesToDelete.flatMap(({ entry }) => [\n\t\t\tdriver.delete(buildHistoryKey(entry.location)),\n\t\t\tdriver.delete(buildEntryMetadataKey(entry.id)),\n\t\t]),\n\t);\n\n\tfor (const { key, entry } of entriesToDelete) {\n\t\tstorage.history.entries.delete(key);\n\t\tstorage.entryMetadata.delete(entry.id);\n\t}\n\n\tstorage.output = undefined;\n\tstorage.flushedOutput = undefined;\n\tstorage.error = undefined;\n\tstorage.flushedError = undefined;\n\tstorage.state = \"sleeping\";\n\tstorage.flushedState = \"sleeping\";\n\n\tawait Promise.all([\n\t\tdriver.delete(buildWorkflowOutputKey()),\n\t\tdriver.delete(buildWorkflowErrorKey()),\n\t\tdriver.set(buildWorkflowStateKey(), serializeWorkflowState(\"sleeping\")),\n\t]);\n\tif (options?.scheduleAlarm ?? true) {\n\t\tawait driver.setAlarm(workflowId, Date.now());\n\t}\n\n\treturn createHistorySnapshot(storage);\n}\n\nfunction findReplayBoundaryEntry(\n\tentries: ReplayEntryRecord[],\n\ttarget: ReplayEntryRecord,\n): ReplayEntryRecord {\n\tlet boundary = target;\n\tlet boundaryDepth = -1;\n\n\tfor (const candidate of entries) {\n\t\tif (candidate.entry.kind.type !== \"loop\") {\n\t\t\tcontinue;\n\t\t}\n\t\tif (\n\t\t\tcandidate.entry.location.length >= target.entry.location.length ||\n\t\t\t!isLocationPrefix(candidate.entry.location, target.entry.location)\n\t\t) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (candidate.entry.location.length > boundaryDepth) {\n\t\t\tboundary = candidate;\n\t\t\tboundaryDepth = candidate.entry.location.length;\n\t\t}\n\t}\n\n\treturn boundary;\n}\n\n/**\n * Internal: Execute the workflow and return the result.\n */\nasync function executeWorkflow<TInput, TOutput>(\n\tworkflowId: string,\n\tworkflowFn: WorkflowFunction<TInput, TOutput>,\n\tinput: TInput,\n\tdriver: EngineDriver,\n\tmessageDriver: WorkflowMessageDriver,\n\tabortController: AbortController,\n\tonHistoryUpdated?: (history: WorkflowHistorySnapshot) => void,\n\tonError?: RunWorkflowOptions[\"onError\"],\n\tlogger?: Logger,\n): Promise<WorkflowResult<TOutput>> {\n\tconst storage = await loadStorage(driver);\n\tconst historyNotifier: HistoryNotifier = onHistoryUpdated\n\t\t? () => onHistoryUpdated(createHistorySnapshot(storage))\n\t\t: undefined;\n\tif (historyNotifier) {\n\t\thistoryNotifier();\n\t}\n\n\tif (logger) {\n\t\tconst entryKeys = Array.from(storage.history.entries.keys());\n\t\tlogger.debug({\n\t\t\tmsg: \"loaded workflow storage\",\n\t\t\tstate: storage.state,\n\t\t\tentryCount: entryKeys.length,\n\t\t\tentries: entryKeys.slice(0, 10),\n\t\t\tnameRegistry: storage.nameRegistry,\n\t\t});\n\t}\n\n\t// Check if workflow was cancelled\n\tif (storage.state === \"cancelled\") {\n\t\tthrow new EvictedError();\n\t}\n\n\t// Input persistence: store on first run, use stored input on resume\n\tconst storedInputBytes = await driver.get(buildWorkflowInputKey());\n\tlet effectiveInput: TInput;\n\n\tif (storedInputBytes) {\n\t\t// Resume: use stored input for deterministic replay\n\t\teffectiveInput = deserializeWorkflowInput<TInput>(storedInputBytes);\n\t} else {\n\t\t// First run: store the input\n\t\teffectiveInput = input;\n\t\tawait driver.set(\n\t\t\tbuildWorkflowInputKey(),\n\t\t\tserializeWorkflowInput(input),\n\t\t);\n\t}\n\n\tif (storage.state === \"rolling_back\") {\n\t\ttry {\n\t\t\tawait executeRollback(\n\t\t\t\tworkflowId,\n\t\t\t\tworkflowFn,\n\t\t\t\teffectiveInput,\n\t\t\t\tdriver,\n\t\t\t\tmessageDriver,\n\t\t\t\tabortController,\n\t\t\t\tstorage,\n\t\t\t\thistoryNotifier,\n\t\t\t\tonError,\n\t\t\t\tlogger,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tif (error instanceof EvictedError) {\n\t\t\t\treturn { state: storage.state };\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\n\t\tstorage.state = \"failed\";\n\t\tawait flush(storage, driver, historyNotifier);\n\n\t\tconst storedError = storage.error\n\t\t\t? new Error(storage.error.message)\n\t\t\t: new Error(\"Workflow failed\");\n\t\tif (storage.error?.name) {\n\t\t\tstoredError.name = storage.error.name;\n\t\t}\n\t\tthrow storedError;\n\t}\n\n\tconst ctx = new WorkflowContextImpl(\n\t\tworkflowId,\n\t\tstorage,\n\t\tdriver,\n\t\tmessageDriver,\n\t\tundefined,\n\t\tabortController,\n\t\t\"forward\",\n\t\tundefined,\n\t\tfalse,\n\t\thistoryNotifier,\n\t\tonError,\n\t\tlogger,\n\t);\n\n\tstorage.state = \"running\";\n\n\ttry {\n\t\tconst output = await workflowFn(ctx, effectiveInput);\n\n\t\tstorage.state = \"completed\";\n\t\tstorage.output = output;\n\t\tawait flush(storage, driver, historyNotifier);\n\t\tawait driver.clearAlarm(workflowId);\n\n\t\treturn { state: \"completed\", output };\n\t} catch (error) {\n\t\tif (error instanceof SleepError) {\n\t\t\treturn await setSleepState(\n\t\t\t\tstorage,\n\t\t\t\tdriver,\n\t\t\t\tworkflowId,\n\t\t\t\terror.deadline,\n\t\t\t\terror.messageNames,\n\t\t\t\thistoryNotifier,\n\t\t\t);\n\t\t}\n\n\t\tif (error instanceof MessageWaitError) {\n\t\t\treturn await setMessageWaitState(\n\t\t\t\tstorage,\n\t\t\t\tdriver,\n\t\t\t\terror.messageNames,\n\t\t\t\thistoryNotifier,\n\t\t\t);\n\t\t}\n\n\t\tif (error instanceof EvictedError) {\n\t\t\treturn await setEvictedState(storage, driver, historyNotifier);\n\t\t}\n\n\t\tif (error instanceof StepFailedError) {\n\t\t\treturn await setRetryState(\n\t\t\t\tstorage,\n\t\t\t\tdriver,\n\t\t\t\tworkflowId,\n\t\t\t\terror.retryAt,\n\t\t\t\thistoryNotifier,\n\t\t\t);\n\t\t}\n\n\t\tif (error instanceof RollbackCheckpointError) {\n\t\t\tawait setFailedState(storage, driver, error, historyNotifier);\n\t\t\tif (onError && !isErrorReported(error)) {\n\t\t\t\tawait notifyError(onError, logger, {\n\t\t\t\t\tworkflow: {\n\t\t\t\t\t\tworkflowId,\n\t\t\t\t\t\terror: extractErrorInfo(error),\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\n\t\t// Unrecoverable error\n\t\tstorage.error = extractErrorInfo(error);\n\t\tstorage.state = \"rolling_back\";\n\t\tawait flush(storage, driver, historyNotifier);\n\n\t\ttry {\n\t\t\tawait executeRollback(\n\t\t\t\tworkflowId,\n\t\t\t\tworkflowFn,\n\t\t\t\teffectiveInput,\n\t\t\t\tdriver,\n\t\t\t\tmessageDriver,\n\t\t\t\tabortController,\n\t\t\t\tstorage,\n\t\t\t\thistoryNotifier,\n\t\t\t\tonError,\n\t\t\t\tlogger,\n\t\t\t);\n\t\t} catch (rollbackError) {\n\t\t\tif (rollbackError instanceof EvictedError) {\n\t\t\t\treturn { state: storage.state };\n\t\t\t}\n\t\t\tthrow rollbackError;\n\t\t}\n\n\t\tstorage.state = \"failed\";\n\t\tawait flush(storage, driver, historyNotifier);\n\t\tif (onError && !isErrorReported(error)) {\n\t\t\tawait notifyError(onError, logger, {\n\t\t\t\tworkflow: {\n\t\t\t\t\tworkflowId,\n\t\t\t\t\terror: extractErrorInfo(error),\n\t\t\t\t},\n\t\t\t});\n\t\t\tif (\n\t\t\t\terror instanceof CriticalError ||\n\t\t\t\terror instanceof RollbackError ||\n\t\t\t\terror instanceof StepExhaustedError\n\t\t\t) {\n\t\t\t\tmarkErrorReported(error);\n\t\t\t}\n\t\t}\n\n\t\tthrow error;\n\t}\n}\n"]}