{"version":3,"file":"state.cjs","names":["instance: unknown","eventSource","event: WorkflowEventData<any>","controller: TransformStreamDefaultController<string>","eventMap: Record<string, WorkflowEvent<any>>","data: string","controller: TransformStreamDefaultController<WorkflowEventData<any>>","#eventMap","eventMap","event: WorkflowEvent<T>","handler: (event: WorkflowEventData<T>) => void","#subscribable","subscribable: Subscribable<[R], void> | null","rootStream: ReadableStream<R> | null","#stream","unsubscribe: () => void","stream: ReadableStream<WorkflowEventData<any>>","response: Response","init?: ResponseInit","reason?: any","transform: ReadableWritablePair<T, R>","options?: StreamPipeOptions","destination: WritableStream<R>","callback: (item: R) => void","item: R","callback: (item: R) => T","options?: ReadableStreamIteratorOptions","limit: number","predicate:\n      | WorkflowEvent<InferWorkflowEventData<R>>\n      | ((event: R) => boolean)\n      | R","predicate:\n      | WorkflowEvent<InferWorkflowEventData<R>>\n      | R\n      | ((item: R) => boolean)","events: R[]","AsyncContext","context: WorkflowContext","properties: Record<string, any>","inheritanceTransformers?: Record<string, InheritanceTransformer>","arg: any","index: any","init?: InitFunc<Input, State>","getContext","workflow: Workflow","context: WorkflowContext","versionObj: [number[], Function][]","context","serializable: SnapshotData","event: WorkflowEvent<any>","counter: number","counter","state: State","events: WorkflowEvent<any>[]","handler: any","serializable: Omit<SnapshotData, \"unrecoverableQueue\">","input?: Input"],"sources":["../src/core/event.ts","../src/core/stream.ts","../src/core/context.ts","../src/middleware/snapshot/stable-hash.ts","../src/middleware/state.ts"],"sourcesContent":["declare const opaqueSymbol: unique symbol;\n\ntype Callback = (evd: WorkflowEventData<any>) => void;\n\ntype Cleanup = () => void;\n\nconst eventMap = new WeakMap<WorkflowEvent<any>, WeakSet<object>>();\nconst refMap = new WeakMap<WorkflowEventData<any>, WorkflowEvent<any>>();\nconst initCallbackMap = new WeakMap<WorkflowEvent<any>, Set<Callback>>();\nlet i = 0;\nlet j = 0;\n\nexport type InferWorkflowEventData<T> = T extends WorkflowEventData<infer U>\n  ? U\n  : T extends WorkflowEvent<infer U>\n    ? U\n    : never;\n\n/**\n * Represents event data flowing through a workflow.\n *\n * Event data is created when an event is instantiated with the `.with()` method.\n * It carries the actual payload and can be processed by event handlers.\n *\n * @typeParam Data - The type of data this event carries\n * @typeParam DebugLabel - Optional debug label for development/debugging\n *\n * @category Events\n * @public\n */\nexport type WorkflowEventData<Data, DebugLabel extends string = string> = {\n  get data(): Data;\n} & { readonly [opaqueSymbol]: DebugLabel };\n\n/**\n * Represents a workflow event type that can be instantiated with data.\n *\n * Events are the core building blocks of workflows. They define the structure\n * of data that flows through the system and can be used to trigger handlers.\n *\n * @typeParam Data - The type of data this event can carry\n * @typeParam DebugLabel - Optional debug label for development/debugging\n *\n * @example\n * ```typescript\n * // Create an event type\n * const UserLoginEvent = workflowEvent<{ userId: string; timestamp: Date }>();\n *\n * // Create event data\n * const loginData = UserLoginEvent.with({\n *   userId: 'user123',\n *   timestamp: new Date()\n * });\n *\n * // Check if data belongs to this event type\n * if (UserLoginEvent.include(someEventData)) {\n *   console.log('User ID:', someEventData.data.userId);\n * }\n * ```\n *\n * @category Events\n * @public\n */\nexport type WorkflowEvent<Data, DebugLabel extends string = string> = {\n  /**\n   * Optional label used for debugging and logging purposes.\n   */\n  debugLabel?: DebugLabel;\n  /**\n   * Unique identifier for the event type, used for serialization and network communication.\n   */\n  readonly uniqueId: string;\n\n  /**\n   * Creates event data with the provided payload.\n   *\n   * @param data - The data payload for this event instance\n   * @returns Event data that can be sent through workflow contexts\n   */\n  with(data: Data): WorkflowEventData<Data, DebugLabel>;\n\n  /**\n   * Type guard to check if unknown event data belongs to this event type.\n   *\n   * @param event - Unknown event data to check\n   * @returns True if the event data is of this event type\n   */\n  include(event: unknown): event is WorkflowEventData<Data, DebugLabel>;\n\n  /**\n   * Registers a callback to be called when this event type is instantiated.\n   *\n   * @param callback - Function to call when event is created\n   * @returns Cleanup function to remove the callback\n   */\n  onInit(callback: Callback): Cleanup;\n} & { readonly [opaqueSymbol]: DebugLabel };\n\n/**\n * Configuration options for creating workflow events.\n *\n * @typeParam DebugLabel - Optional debug label type\n *\n * @category Events\n * @public\n */\nexport type WorkflowEventConfig<DebugLabel extends string = string> = {\n  /** Optional debug label for development and logging */\n  debugLabel?: DebugLabel;\n  /** Optional unique identifier for the event type */\n  uniqueId?: string;\n};\n\n/**\n * Creates a new workflow event type.\n *\n * This is the primary factory function for creating event types that can be used\n * in workflows. Each event type can carry specific data and be used to trigger\n * handlers throughout the workflow system.\n *\n * @typeParam Data - The type of data this event will carry (defaults to void)\n * @typeParam DebugLabel - Optional debug label type for development\n *\n * @param config - Optional configuration for the event type\n * @returns A new workflow event type that can be instantiated with data\n *\n * @example\n * ```typescript\n * // Create a simple event with no data\n * const StartEvent = workflowEvent();\n *\n * // Create an event that carries user data\n * const UserEvent = workflowEvent<{ name: string; email: string }>({\n *   debugLabel: 'UserEvent'\n * });\n *\n * // Create event instances\n * const start = StartEvent.with();\n * const user = UserEvent.with({ name: 'John', email: 'john@example.com' });\n * ```\n *\n * @category Events\n * @public\n */\nexport const workflowEvent = <Data = void, DebugLabel extends string = string>(\n  config?: WorkflowEventConfig<DebugLabel>,\n): WorkflowEvent<Data, DebugLabel> => {\n  const l1 = `${i++}`;\n  const cb = new Set<Callback>();\n  const event = {\n    debugLabel: config?.debugLabel ?? l1,\n    include: (\n      instance: WorkflowEventData<any>,\n    ): instance is WorkflowEventData<Data> => s.has(instance),\n    with: (data: Data) => {\n      const l2 = `${j++}`;\n      const ref = {\n        [Symbol.toStringTag]:\n          config?.debugLabel ?? `WorkflowEvent(${l1}.${l2})`,\n        toString: () =>\n          config?.debugLabel ? config.debugLabel : `WorkflowEvent(${l1}.${l2})`,\n        toJSON: () => {\n          return {\n            type: config?.debugLabel ? config.debugLabel : l1,\n            data,\n          };\n        },\n        get data() {\n          return data;\n        },\n      } as unknown as WorkflowEventData<Data, DebugLabel>;\n      s.add(ref);\n      refMap.set(ref, event);\n      cb.forEach((c) => c(ref));\n      return ref;\n    },\n    onInit: (callback: Callback) => {\n      cb.add(callback);\n      return () => {\n        cb.delete(callback);\n      };\n    },\n  } as unknown as WorkflowEvent<Data, DebugLabel>;\n\n  const s = new WeakSet();\n  eventMap.set(event, s);\n\n  initCallbackMap.set(event, cb);\n\n  Object.defineProperty(event, Symbol.toStringTag, {\n    get: () => event?.debugLabel ?? `WorkflowEvent<${l1}>`,\n  });\n\n  Object.defineProperty(event, \"displayName\", {\n    value: event?.debugLabel ?? `WorkflowEvent<${l1}>`,\n  });\n\n  let uniqueId = config?.uniqueId;\n\n  Object.defineProperty(event, \"uniqueId\", {\n    get: () => {\n      if (!uniqueId) {\n        uniqueId = l1;\n      }\n      return uniqueId;\n    },\n    set: () => {\n      throw new Error(\"uniqueId is readonly\");\n    },\n  });\n\n  event.toString = () => config?.debugLabel ?? `WorkflowEvent<${l1}>`;\n  return event;\n};\n\n// utils\nexport const isWorkflowEvent = (\n  instance: unknown,\n): instance is WorkflowEvent<any> =>\n  typeof instance === \"object\" && instance !== null\n    ? eventMap.has(instance as any)\n    : false;\nexport const isWorkflowEventData = (\n  instance: unknown,\n): instance is WorkflowEventData<any> =>\n  typeof instance === \"object\" && instance !== null\n    ? refMap.has(instance as any)\n    : false;\nexport const eventSource = (\n  instance: unknown,\n): WorkflowEvent<any> | undefined =>\n  typeof instance === \"object\" && instance !== null\n    ? refMap.get(instance as any)\n    : undefined;\n\n// OR Event Implementation\n\nexport type OrEvent<Events extends WorkflowEvent<any>[]> =\n  WorkflowEvent<any> & {\n    _type: \"or\";\n    events: Events;\n  };\n\nexport const or = <const Events extends WorkflowEvent<any>[]>(\n  ...events: Events\n): OrEvent<Events> => {\n  const debugLabel = `or(${events.map((e) => e.debugLabel || e.uniqueId).join(\", \")})`;\n  const l1 = `or_${i++}`;\n\n  const orEvent = {\n    _type: \"or\" as const,\n    events,\n    debugLabel,\n    include: (eventData: unknown): eventData is WorkflowEventData<any> => {\n      // Accept events from any constituent event OR events created by this OR event\n      return (\n        events.some((event) => event.include(eventData)) ||\n        s.has(eventData as any)\n      );\n    },\n    with: (data: any) => {\n      const ref = {\n        [Symbol.toStringTag]: debugLabel,\n        toString: () => debugLabel,\n        toJSON: () => ({\n          type: debugLabel,\n          data,\n        }),\n        get data() {\n          return data;\n        },\n      } as unknown as WorkflowEventData<any>;\n      s.add(ref);\n      refMap.set(ref, orEvent);\n      return ref;\n    },\n  } as unknown as OrEvent<Events>;\n\n  const s = new WeakSet();\n  eventMap.set(orEvent as any, s);\n\n  let uniqueId: string;\n  Object.defineProperty(orEvent, \"uniqueId\", {\n    get: () => {\n      if (!uniqueId) {\n        uniqueId = l1;\n      }\n      return uniqueId;\n    },\n    set: () => {\n      throw new Error(\"uniqueId is readonly\");\n    },\n  });\n\n  Object.defineProperty(orEvent, Symbol.toStringTag, {\n    get: () => debugLabel,\n  });\n\n  Object.defineProperty(orEvent, \"displayName\", {\n    value: debugLabel,\n  });\n\n  (orEvent as any).toString = () => debugLabel;\n\n  return orEvent;\n};\n","import {\n  eventSource,\n  type InferWorkflowEventData,\n  isWorkflowEvent,\n  type WorkflowEvent,\n  type WorkflowEventData,\n} from \"./event\";\nimport { createSubscribable, type Subscribable } from \"./utils\";\n\nclass JsonEncodeTransform extends TransformStream<\n  WorkflowEventData<any>,\n  string\n> {\n  constructor() {\n    super({\n      transform: (\n        event: WorkflowEventData<any>,\n        controller: TransformStreamDefaultController<string>,\n      ) => {\n        if (eventSource(event)) {\n          controller.enqueue(\n            JSON.stringify({\n              data: (event as WorkflowEventData<any>).data,\n              uniqueId: eventSource(event)!.uniqueId,\n            }) + \"\\n\",\n          );\n        }\n      },\n    });\n  }\n}\n\nclass JsonDecodeTransform extends TransformStream<\n  string,\n  WorkflowEventData<any>\n> {\n  #eventMap: Record<string, WorkflowEvent<any>>;\n\n  constructor(eventMap: Record<string, WorkflowEvent<any>>) {\n    super({\n      transform: (\n        data: string,\n        controller: TransformStreamDefaultController<WorkflowEventData<any>>,\n      ) => {\n        const lines = data\n          .split(\"\\n\")\n          .map((line) => line.trim())\n          .filter((line) => line.length > 0);\n        lines.forEach((line) => {\n          const eventData = JSON.parse(line) as {\n            data: ReturnType<WorkflowEvent<any>[\"with\"]>;\n            uniqueId: string;\n          };\n          const targetEvent = Object.values(this.#eventMap).find(\n            (e) => e.uniqueId === eventData.uniqueId,\n          );\n          if (targetEvent) {\n            const ev = targetEvent.with(\n              eventData.data,\n            ) as WorkflowEventData<any>;\n            controller.enqueue(ev);\n          } else {\n            console.warn(`Unknown event: ${eventData.uniqueId}`);\n          }\n        });\n      },\n    });\n    this.#eventMap = eventMap;\n  }\n}\n\n/**\n * A reactive stream for processing workflow events.\n *\n * WorkflowStream extends the standard ReadableStream to provide specialized\n * methods for filtering, transforming, and consuming workflow events.\n * It supports reactive patterns and can be used to build complex event\n * processing pipelines.\n *\n * @typeParam R - The type of data flowing through the stream\n *\n * @example\n * ```typescript\n * // Get stream from workflow context\n * const stream = context.stream;\n *\n * // Filter for specific events\n * const userEvents = stream.filter(UserEvent);\n *\n * // Transform events\n * const processed = stream.map(event => ({\n *   type: event.constructor.name,\n *   timestamp: Date.now(),\n *   data: event.data\n * }));\n *\n * // Consume events\n * for await (const event of stream.take(10)) {\n *   console.log('Received:', event);\n * }\n * ```\n *\n * @category Streaming\n * @public\n */\nexport class WorkflowStream<R = any>\n  extends ReadableStream<R>\n  implements AsyncIterable<R>\n{\n  #stream: ReadableStream<R>;\n  #subscribable: Subscribable<[data: R], void>;\n\n  /**\n   * Subscribe to specific workflow events.\n   *\n   * @param event - The event type to listen for\n   * @param handler - Function to handle the event\n   * @returns Unsubscribe function\n   *\n   * @example\n   * ```typescript\n   * const unsubscribe = stream.on(UserEvent, (event) => {\n   *   console.log('User event:', event.data);\n   * });\n   *\n   * // Later...\n   * unsubscribe();\n   * ```\n   */\n  on<T>(\n    event: WorkflowEvent<T>,\n    handler: (event: WorkflowEventData<T>) => void,\n  ): () => void {\n    return this.#subscribable.subscribe((ev) => {\n      if (event.include(ev)) {\n        handler(ev);\n      }\n    });\n  }\n\n  constructor(\n    subscribable: Subscribable<[R], void>,\n    rootStream: ReadableStream<R>,\n  );\n  constructor(subscribable: Subscribable<[R], void>, rootStream: null);\n  constructor(subscribable: null, rootStream: ReadableStream<R> | null);\n  constructor(\n    subscribable: Subscribable<[R], void> | null,\n    rootStream: ReadableStream<R> | null,\n  ) {\n    if (!subscribable && !rootStream) {\n      throw new TypeError(\n        \"Either subscribable or root stream must be provided\",\n      );\n    }\n    super();\n    if (!subscribable) {\n      this.#subscribable = createSubscribable<[data: R], void>();\n      this.#stream = rootStream!.pipeThrough(\n        new TransformStream({\n          transform: (ev, controller) => {\n            this.#subscribable.publish(ev);\n            controller.enqueue(ev);\n          },\n        }),\n      );\n      return;\n    } else {\n      this.#subscribable = subscribable;\n      let unsubscribe: () => void;\n      this.#stream =\n        rootStream ??\n        new ReadableStream<R>({\n          start: (controller) => {\n            unsubscribe = subscribable.subscribe((event) => {\n              controller.enqueue(event);\n            });\n          },\n          cancel: () => {\n            unsubscribe();\n          },\n        });\n    }\n  }\n\n  /**\n   * Create a WorkflowStream from a standard ReadableStream.\n   *\n   * @param stream - The ReadableStream to wrap\n   * @returns A new WorkflowStream instance\n   */\n  static fromReadableStream<T = any>(\n    stream: ReadableStream<WorkflowEventData<any>>,\n  ): WorkflowStream<T> {\n    return new WorkflowStream(\n      null,\n      stream.pipeThrough(\n        new TransformStream<WorkflowEventData<any>>({\n          transform: (event, controller) => {\n            controller.enqueue(event);\n          },\n        }),\n      ),\n    );\n  }\n\n  /**\n   * Create a WorkflowStream from an HTTP Response.\n   *\n   * @param response - The HTTP Response containing workflow events\n   * @param eventMap - Map of event unique IDs to event constructors\n   * @returns A new WorkflowStream instance\n   */\n  static fromResponse(\n    response: Response,\n    eventMap: Record<string, WorkflowEvent<any>>,\n  ): WorkflowStream<WorkflowEventData<any>> {\n    const body = response.body;\n    if (!body) {\n      throw new Error(\"Response body is not readable\");\n    }\n    return new WorkflowStream(\n      null,\n      body\n        .pipeThrough(new TextDecoderStream())\n        .pipeThrough(new JsonDecodeTransform(eventMap)),\n    );\n  }\n\n  /**\n   * Convert the stream to an HTTP Response.\n   *\n   * @param init - Optional ResponseInit parameters\n   * @param transformer - Optional custom transformer (defaults to JSON encoding)\n   * @returns HTTP Response containing the stream data\n   */\n  toResponse(\n    init?: ResponseInit,\n    transformer = new JsonEncodeTransform(),\n  ): R extends WorkflowEventData<any> ? Response : never {\n    return new Response(\n      (this.#stream as ReadableStream<WorkflowEventData<any>>)\n        .pipeThrough<string>(transformer)\n        .pipeThrough(new TextEncoderStream()),\n      init,\n    ) as any;\n  }\n\n  // ReadableStream compatibility methods - marked as internal to hide from main API docs\n  /** @internal */\n  get locked() {\n    return this.#stream.locked;\n  }\n\n  /** @internal */\n  [Symbol.asyncIterator](): ReadableStreamAsyncIterator<R> {\n    return this.#stream[Symbol.asyncIterator]();\n  }\n\n  /** @internal */\n  cancel(reason?: any): Promise<void> {\n    return this.#stream.cancel(reason);\n  }\n\n  /** @internal */\n  getReader(options: { mode: \"byob\" }): ReadableStreamBYOBReader;\n  /** @internal */\n  getReader(): ReadableStreamDefaultReader<R>;\n  /** @internal */\n  getReader(options?: ReadableStreamGetReaderOptions): ReadableStreamReader<R>;\n  getReader(): any {\n    return this.#stream.getReader();\n  }\n\n  /** @internal */\n  pipeThrough<T>(\n    transform: ReadableWritablePair<T, R>,\n    options?: StreamPipeOptions,\n  ): WorkflowStream<T> {\n    const stream = this.#stream.pipeThrough(transform, options) as any;\n    return new WorkflowStream<T>(null, stream);\n  }\n\n  /** @internal */\n  pipeTo(\n    destination: WritableStream<R>,\n    options?: StreamPipeOptions,\n  ): Promise<void> {\n    return this.#stream.pipeTo(destination, options);\n  }\n\n  /** @internal */\n  tee(): [WorkflowStream<R>, WorkflowStream<R>] {\n    const [l, r] = this.#stream.tee();\n    return [\n      new WorkflowStream(this.#subscribable, l),\n      new WorkflowStream(this.#subscribable, r),\n    ];\n  }\n\n  /**\n   * Process each item in the stream with a callback function.\n   *\n   * @param callback - Function to call for each item\n   * @returns Promise that resolves when all items are processed\n   *\n   * @example\n   * ```typescript\n   * await stream.forEach(event => {\n   *   console.log('Processing:', event);\n   * });\n   * ```\n   */\n  forEach(callback: (item: R) => void): Promise<void> {\n    return this.#stream.pipeTo(\n      new WritableStream({\n        write: (item: R) => {\n          callback(item);\n        },\n      }),\n    );\n  }\n\n  /**\n   * Transform each item in the stream.\n   *\n   * @param callback - Function to transform each item\n   * @returns A new WorkflowStream with transformed items\n   *\n   * @example\n   * ```typescript\n   * const timestamps = stream.map(event => ({\n   *   ...event,\n   *   timestamp: Date.now()\n   * }));\n   * ```\n   */\n  map<T>(callback: (item: R) => T): WorkflowStream<T> {\n    return this.pipeThrough<T>(\n      new TransformStream({\n        transform: (item, controller) => {\n          controller.enqueue(callback(item));\n        },\n      }),\n    );\n  }\n\n  /** @internal */\n  values(\n    options?: ReadableStreamIteratorOptions,\n  ): ReadableStreamAsyncIterator<R> {\n    return this.#stream.values(options);\n  }\n\n  /**\n   * Take only the first N items from the stream.\n   *\n   * @param limit - Maximum number of items to take\n   * @returns A new WorkflowStream limited to the specified number of items\n   *\n   * @example\n   * ```typescript\n   * const firstTen = stream.take(10);\n   * for await (const event of firstTen) {\n   *   console.log(event);\n   * }\n   * ```\n   */\n  take(limit: number): WorkflowStream<R> {\n    let count = 0;\n    return this.pipeThrough(\n      new TransformStream({\n        transform: (ev, controller) => {\n          if (count < limit) {\n            controller.enqueue(ev);\n            count++;\n          }\n          if (count >= limit) {\n            controller.terminate();\n          }\n        },\n      }),\n    );\n  }\n\n  /**\n   * Filter the stream to include only items matching the predicate.\n   *\n   * @param predicate - Event type, function, or value to filter by\n   * @returns A new WorkflowStream containing only matching items\n   *\n   * @example\n   * ```typescript\n   * // Filter by event type\n   * const userEvents = stream.filter(UserEvent);\n   *\n   * // Filter by function\n   * const importantEvents = stream.filter(event => event.priority === 'high');\n   *\n   * // Filter by specific value\n   * const specificEvent = stream.filter(myEventInstance);\n   * ```\n   */\n  filter(\n    predicate: R extends WorkflowEventData<any>\n      ? WorkflowEvent<InferWorkflowEventData<R>>\n      : never,\n  ): WorkflowStream<R>;\n  filter(predicate: R): WorkflowStream<R>;\n  filter(predicate: (event: R) => boolean): WorkflowStream<R>;\n  filter(\n    predicate:\n      | WorkflowEvent<InferWorkflowEventData<R>>\n      | ((event: R) => boolean)\n      | R,\n  ): WorkflowStream<R> {\n    return this.pipeThrough(\n      new TransformStream({\n        transform: (ev, controller) => {\n          if (\n            typeof predicate === \"function\"\n              ? (predicate as (event: R) => boolean)(ev)\n              : isWorkflowEvent(predicate)\n                ? predicate.include(ev)\n                : predicate === ev\n          ) {\n            controller.enqueue(ev);\n          }\n        },\n      }),\n    );\n  }\n\n  /**\n   * Continue the stream until the predicate is met, then terminate.\n   *\n   * @param predicate - Event type, function, or value to stop at\n   * @returns A new WorkflowStream that terminates when the predicate is met\n   *\n   * @example\n   * ```typescript\n   * // Stop at completion event\n   * const processingEvents = stream.until(CompletionEvent);\n   *\n   * // Stop when condition is met\n   * const beforeError = stream.until(event => event.type === 'error');\n   *\n   * // Stop at specific event instance\n   * const beforeSpecific = stream.until(myEventInstance);\n   * ```\n   */\n  until(\n    predicate: R extends WorkflowEventData<any>\n      ? WorkflowEvent<InferWorkflowEventData<R>>\n      : never,\n  ): WorkflowStream<R>;\n  until(predicate: (item: R) => boolean): WorkflowStream<R>;\n  until(item: R): WorkflowStream<R>;\n  until(\n    predicate:\n      | WorkflowEvent<InferWorkflowEventData<R>>\n      | R\n      | ((item: R) => boolean),\n  ): WorkflowStream<R> {\n    return this.pipeThrough(\n      new TransformStream({\n        transform: (ev, controller) => {\n          controller.enqueue(ev);\n          if (\n            typeof predicate === \"function\"\n              ? (predicate as (event: R) => boolean)(ev)\n              : isWorkflowEvent(predicate)\n                ? predicate.include(ev)\n                : predicate === ev\n          ) {\n            controller.terminate();\n          }\n        },\n      }),\n    );\n  }\n\n  /**\n   * Continue the stream until a matching event is found, then return that event.\n   *\n   * @param predicate - Event type, function, or value to wait for\n   * @returns Promise resolving to the matching event\n   *\n   * @example\n   * ```typescript\n   * // Wait for completion event and return it directly\n   * const result = await stream.untilEvent(CompletionEvent);\n   * console.log('Final result:', result.data);\n   *\n   * // Wait for condition and return matching event\n   * const errorEvent = await stream.untilEvent(event => event.type === 'error');\n   * ```\n   */\n  async untilEvent(\n    predicate: R extends WorkflowEventData<any>\n      ? WorkflowEvent<InferWorkflowEventData<R>>\n      : never,\n  ): Promise<R>;\n  async untilEvent(predicate: (item: R) => boolean): Promise<R>;\n  async untilEvent(item: R): Promise<R>;\n  async untilEvent(\n    predicate:\n      | WorkflowEvent<InferWorkflowEventData<R>>\n      | R\n      | ((item: R) => boolean),\n  ): Promise<R> {\n    const events = await this.until(predicate as any).toArray();\n    const lastEvent = events[events.length - 1];\n    if (!lastEvent) {\n      throw new Error(\"Stream ended without matching event\");\n    }\n\n    // Check if the last event actually matches the predicate\n    const matches =\n      typeof predicate === \"function\"\n        ? (predicate as (event: R) => boolean)(lastEvent)\n        : isWorkflowEvent(predicate)\n          ? predicate.include(lastEvent)\n          : predicate === lastEvent;\n\n    if (!matches) {\n      throw new Error(\"Stream ended without matching event\");\n    }\n\n    return lastEvent;\n  }\n\n  /**\n   * Collect all items from the stream into an array.\n   *\n   * @returns Promise resolving to an array of all stream items\n   *\n   * @example\n   * ```typescript\n   * const events = await stream.take(5).toArray();\n   * console.log('Collected events:', events);\n   * ```\n   */\n  async toArray(): Promise<R[]> {\n    const events: R[] = [];\n    await this.pipeTo(\n      new WritableStream({\n        write: (event) => {\n          events.push(event);\n        },\n      }),\n    );\n    return events;\n  }\n}\n","import type {\n  WorkflowEvent,\n  WorkflowEventData,\n} from \"@llamaindex/workflow-core\";\nimport { AsyncContext } from \"@llamaindex/workflow-core/async-context\";\nimport { WorkflowStream } from \"./stream\";\nimport {\n  createSubscribable,\n  flattenEvents,\n  getSubscribers,\n  isEventData,\n  isPromiseLike,\n  type Subscribable,\n} from \"./utils\";\n\nexport type Handler<\n  AcceptEvents extends WorkflowEvent<any>[],\n  Result extends WorkflowEventData<any> | void,\n  Context extends WorkflowContext = WorkflowContext,\n> = (\n  context: Context,\n  ...events: {\n    [K in keyof AcceptEvents]: ReturnType<AcceptEvents[K][\"with\"]>;\n  }\n) => Result | Promise<Result>;\n\ntype BaseHandlerContext = {\n  abortController: AbortController;\n  handler: Handler<WorkflowEvent<any>[], any>;\n  // events that are accepted by the handler\n  inputEvents: WorkflowEvent<any>[];\n  // events data that are accepted by the handler\n  inputs: WorkflowEventData<any>[];\n  // events data that are emitted by the handler\n  outputs: WorkflowEventData<any>[];\n\n  //#region linked list data structure\n  prev: HandlerContext;\n  next: Set<HandlerContext>;\n  root: HandlerContext;\n  //#endregion\n};\n\ntype SyncHandlerContext = BaseHandlerContext & {\n  async: false;\n  pending: null;\n};\n\ntype AsyncHandlerContext = BaseHandlerContext & {\n  async: true;\n  pending: Promise<WorkflowEventData<any> | void> | null;\n};\n\nexport type HandlerContext = AsyncHandlerContext | SyncHandlerContext;\n\nexport type ContextNext = (\n  context: HandlerContext,\n  next: (context: HandlerContext) => void,\n) => void;\n\n/**\n * Execution context for workflow event processing.\n *\n * The workflow context provides the runtime environment for executing handlers\n * and managing event flow. It offers access to the event stream, abort signals,\n * and methods for sending events within the workflow.\n *\n * @example\n * ```typescript\n * // Use the current context (first parameter inside a handler)\n * const { sendEvent, stream, signal } = context;\n *\n * // Send events\n * sendEvent(\n *   ProcessEvent.with({ step: 'validation' }),\n *   LogEvent.with({ message: 'Processing started' })\n * );\n *\n * // Access the event stream\n * await stream.filter(CompletionEvent).take(1).toArray();\n *\n * // Check for cancellation\n * if (signal.aborted) {\n *   throw new Error('Operation cancelled');\n * }\n * ```\n *\n * @category Context\n * @public\n */\nexport type WorkflowContext = {\n  /**\n   * Stream of all events flowing through this workflow context.\n   * Can be used to listen for specific events or create reactive processing chains.\n   */\n  get stream(): WorkflowStream<WorkflowEventData<any>>;\n\n  /**\n   * Abort signal that indicates if the workflow has been cancelled.\n   * Handlers should check this periodically for long-running operations.\n   */\n  get signal(): AbortSignal;\n\n  /**\n   * Sends one or more events into the workflow for processing.\n   * Events will be delivered to all matching handlers asynchronously.\n   *\n   * @param events - Event data instances to send\n   */\n  sendEvent: (...events: WorkflowEventData<any>[]) => void;\n\n  /**\n   * @internal\n   */\n  __internal__call_context: Subscribable<\n    Parameters<ContextNext>,\n    ReturnType<ContextNext>\n  >;\n  __internal__call_send_event: Subscribable<\n    [event: WorkflowEventData<any>, handlerContext: HandlerContext],\n    void\n  >;\n  __internal__property_inheritance_handlers?: Map<\n    string,\n    InheritanceTransformer\n  >;\n};\n\nexport type InheritanceTransformer = (\n  handlerContext: WorkflowContext,\n  originalDescriptor: PropertyDescriptor,\n) => PropertyDescriptor;\n\nexport const _executorAsyncLocalStorage =\n  new AsyncContext.Variable<WorkflowContext>();\n\n/**\n * @deprecated Use the context parameter directly from workflow handlers instead.\n * The context passed to handlers already includes all state properties.\n *\n * @example\n * ```ts\n * workflow.handle([startEvent], (context, event) => {\n *   const { sendEvent } = context;\n *   sendEvent(processEvent.with());\n * });\n * ```\n */\nexport function getContext(): WorkflowContext {\n  const context = _executorAsyncLocalStorage.get();\n  if (!context) {\n    throw new Error(\"No current context found\");\n  }\n  return context;\n}\n\n/**\n * Use this function to add or extend properties of the root context.\n * Called by middleware's createContext to update the root context.\n * Handler-scoped contexts will automatically inherit these properties from the root context.\n * Never create a new object (e.g., using a spread `{...context}`) in your middleware's createContext.\n *\n * @param context The context to extend\n * @param properties The properties to add to the context\n * @param inheritanceTransformers The inheritance transformers to apply to existing properties (optional)\n */\nexport function extendContext(\n  context: WorkflowContext,\n  properties: Record<string, any>,\n  inheritanceTransformers?: Record<string, InheritanceTransformer>,\n): void {\n  // Add simple properties directly to the context (these inherit normally via prototype chain)\n  Object.assign(context, properties);\n\n  // Register inheritance transformers for properties that need custom inheritance behavior\n  if (inheritanceTransformers) {\n    if (!context.__internal__property_inheritance_handlers) {\n      context.__internal__property_inheritance_handlers = new Map();\n    }\n\n    for (const [propertyKey, transformer] of Object.entries(\n      inheritanceTransformers,\n    )) {\n      context.__internal__property_inheritance_handlers.set(\n        propertyKey,\n        transformer,\n      );\n\n      // Apply the transformer to the root context immediately\n      const rootDescriptor = Object.getOwnPropertyDescriptor(\n        context,\n        propertyKey,\n      );\n      if (rootDescriptor) {\n        const newDescriptor = transformer(context, rootDescriptor);\n        Object.defineProperty(context, propertyKey, newDescriptor);\n      }\n    }\n  }\n}\n\nconst handlerContextAsyncLocalStorage =\n  new AsyncContext.Variable<HandlerContext>();\n\nconst eventContextWeakMap = new WeakMap<\n  WorkflowEventData<any>,\n  HandlerContext\n>();\n\nexport type ExecutorParams = {\n  listeners: ReadonlyMap<\n    WorkflowEvent<any>[],\n    Set<Handler<WorkflowEvent<any>[], WorkflowEventData<any> | void>>\n  >;\n};\n\nexport const createContext = ({\n  listeners,\n}: ExecutorParams): WorkflowContext => {\n  const queue: WorkflowEventData<any>[] = [];\n  // eslint-disable-next-line prefer-const\n  let rootWorkflowContext: WorkflowContext;\n  const runHandler = (\n    handler: Handler<WorkflowEvent<any>[], any>,\n    inputEvents: WorkflowEvent<any>[],\n    inputs: WorkflowEventData<any>[],\n    parentContext: HandlerContext,\n  ): void => {\n    let handlerAbortController: AbortController;\n    const handlerContext: HandlerContext = {\n      get abortController() {\n        if (!handlerAbortController) {\n          handlerAbortController = new AbortController();\n        }\n        return handlerAbortController;\n      },\n      async:\n        \"constructor\" in handler\n          ? handler.constructor.name === \"AsyncFunction\"\n          : false,\n      pending: null,\n      handler,\n      inputEvents,\n      inputs,\n      outputs: [],\n      prev: parentContext,\n      next: new Set(),\n      get root() {\n        return handlerRootContext;\n      },\n    };\n    handlerContext.prev.next.add(handlerContext);\n    // Use prototype chain to inherit the properties of the root workflow context for the specific context for the handler\n    const specificContext = createWorkflowContext(handlerContext);\n    const workflowContext = Object.create(rootWorkflowContext);\n    const specificDescriptors =\n      Object.getOwnPropertyDescriptors(specificContext);\n\n    // Apply inheritance transformers if available\n    if (rootWorkflowContext.__internal__property_inheritance_handlers) {\n      for (const [\n        propertyKey,\n        transformer,\n      ] of rootWorkflowContext.__internal__property_inheritance_handlers) {\n        if (propertyKey in specificDescriptors) {\n          const originalDescriptor = specificDescriptors[propertyKey];\n          if (originalDescriptor) {\n            const newDescriptor = transformer(\n              workflowContext,\n              originalDescriptor,\n            );\n            specificDescriptors[propertyKey] = newDescriptor;\n          }\n        }\n      }\n    }\n\n    Object.defineProperties(workflowContext, specificDescriptors);\n    handlerContextAsyncLocalStorage.run(handlerContext, () => {\n      const cbs = [\n        ...new Set([\n          ...getSubscribers(rootWorkflowContext.__internal__call_context),\n          ...getSubscribers(workflowContext.__internal__call_context),\n        ]),\n      ];\n      _executorAsyncLocalStorage.run(workflowContext, () => {\n        //#region middleware\n        let i = 0;\n        const next = (context: HandlerContext) => {\n          if (i === cbs.length) {\n            let result: any;\n            try {\n              result = context.handler(workflowContext, ...context.inputs);\n            } catch (error) {\n              if (handlerAbortController ?? rootAbortController) {\n                (handlerAbortController ?? rootAbortController).abort(error);\n              } else {\n                console.error(\"unhandled error in handler\", error);\n                throw error;\n              }\n            }\n            // return value is a special event\n            if (isPromiseLike(result)) {\n              (handlerContext as any).async = true;\n              (handlerContext as any).pending = result.then((event) => {\n                if (isEventData(event)) {\n                  workflowContext.sendEvent(event);\n                }\n                return event;\n              });\n            } else if (isEventData(result)) {\n              workflowContext.sendEvent(result);\n            }\n          }\n          const cb = cbs[i];\n          if (cb) {\n            i++;\n            cb(context, next);\n          }\n        };\n        next(handlerContext);\n        //#endregion\n      });\n    });\n  };\n  const queueUpdateCallback = (handlerContext: HandlerContext) => {\n    const queueSnapshot = [...queue];\n    [...listeners]\n      .filter(([events]) => {\n        const inputs = flattenEvents(events, queueSnapshot);\n        return inputs.length === events.length;\n      })\n      .map(([events, handlers]) => {\n        const inputs = flattenEvents(events, queueSnapshot);\n        inputs.forEach((input) => {\n          queue.splice(queue.indexOf(input), 1);\n        });\n        for (const handler of handlers) {\n          runHandler(handler, events, inputs, handlerContext);\n        }\n      });\n  };\n  const createWorkflowContext = (\n    handlerContext: HandlerContext,\n  ): WorkflowContext => {\n    let lazyLoadStream: WorkflowStream | null = null;\n    return {\n      get stream() {\n        if (!lazyLoadStream) {\n          const subscribable = createSubscribable<\n            [event: WorkflowEventData<any>],\n            void\n          >();\n          rootWorkflowContext.__internal__call_send_event.subscribe(\n            (newEvent: WorkflowEventData<any>) => {\n              let currentEventContext = eventContextWeakMap.get(newEvent);\n              while (currentEventContext) {\n                if (currentEventContext === handlerContext) {\n                  subscribable.publish(newEvent);\n                  break;\n                }\n                currentEventContext = currentEventContext.prev;\n              }\n            },\n          );\n          lazyLoadStream = new WorkflowStream(subscribable, null);\n        }\n        return lazyLoadStream;\n      },\n      get signal() {\n        return handlerContext.abortController.signal;\n      },\n      sendEvent: (...events) => {\n        events.forEach((event) => {\n          eventContextWeakMap.set(event, handlerContext);\n          handlerContext.outputs.push(event);\n          queue.push(event);\n          rootWorkflowContext.__internal__call_send_event.publish(\n            event,\n            handlerContext,\n          );\n          queueUpdateCallback(handlerContext);\n        });\n      },\n      __internal__call_context: createSubscribable(),\n      __internal__call_send_event: createSubscribable(),\n    };\n  };\n\n  let rootAbortController = new AbortController();\n  const handlerRootContext: HandlerContext = {\n    get abortController() {\n      if (!rootAbortController) {\n        rootAbortController = new AbortController();\n      }\n      return rootAbortController;\n    },\n    async: false,\n    pending: null,\n    inputEvents: [],\n    inputs: [],\n    outputs: [],\n    handler: null!,\n    prev: null!,\n    next: new Set(),\n    get root() {\n      return handlerRootContext;\n    },\n  };\n\n  rootWorkflowContext = createWorkflowContext(handlerRootContext);\n  return rootWorkflowContext;\n};\n","// Ref: https://github.com/shuding/stable-hash/blob/main/src/index.ts\nexport function createStableHash() {\n  // Use WeakMap to store the object-key mapping so the objects can still be\n  // garbage collected. WeakMap uses a hashtable under the hood, so the lookup\n  // complexity is almost O(1).\n  const table = new WeakMap<object, string>();\n\n  // A counter of the key.\n  let counter = 0;\n\n  // A stable hash implementation that supports:\n  //  - Fast and ensures unique hash properties\n  //  - Handles unserializable values\n  //  - Handles object key ordering\n  //  - Generates short results\n  //\n  // This is not a serialization function, and the result is not guaranteed to be\n  // parsable.\n  return function stableHash(arg: any): string {\n    const type = typeof arg;\n    const constructor = arg && arg.constructor;\n    const isDate = constructor == Date;\n\n    if (Object(arg) === arg && !isDate && constructor != RegExp) {\n      // Object/function, not null/date/regexp. Use WeakMap to store the id first.\n      // If it's already hashed, directly return the result.\n      let result = table.get(arg);\n      if (result) return result;\n      // Store the hash first for circular reference detection before entering the\n      // recursive `stableHash` calls.\n      // For other objects like set and map, we use this id directly as the hash.\n      result = ++counter + \"~\";\n      table.set(arg, result);\n      let index: any;\n\n      if (constructor == Array) {\n        // Array.\n        result = \"@\";\n        for (index = 0; index < arg.length; index++) {\n          result += stableHash(arg[index]) + \",\";\n        }\n        table.set(arg, result);\n      } else if (constructor == Object) {\n        // Object, sort keys.\n        result = \"#\";\n        const keys = Object.keys(arg).sort();\n        while ((index = keys.pop() as string) !== undefined) {\n          if (arg[index] !== undefined) {\n            result += index + \":\" + stableHash(arg[index]) + \",\";\n          }\n        }\n        table.set(arg, result);\n      }\n      return result;\n    }\n    if (isDate) return arg.toJSON();\n    if (type == \"symbol\") return arg.toString();\n    return type == \"string\" ? JSON.stringify(arg) : \"\" + arg;\n  };\n}\n","import {\n  eventSource,\n  getContext,\n  type Workflow,\n  type WorkflowContext,\n  type Workflow as WorkflowCore,\n  type WorkflowEvent,\n  type WorkflowEventData,\n} from \"@llamaindex/workflow-core\";\nimport type { Handler, HandlerContext } from \"../core/context\";\nimport { extendContext } from \"../core/context\";\nimport { createStableHash } from \"./snapshot/stable-hash\";\n\nexport interface SnapshotData {\n  queue: [data: any, id: number][];\n  /**\n   * These events are not recoverable because they are not in any handler\n   *\n   * This is useful when you have `messageEvent` but you don't have any handler for it\n   */\n  unrecoverableQueue: any[];\n  /**\n   * This is the version of the snapshot\n   *\n   * Change any of the handlers will change the version\n   */\n  version: string;\n\n  /**\n   * Save the current serializable state of the workflow\n   * This state will be restored when you resume the workflow\n   */\n  state?: string | undefined;\n}\n\nexport type SnapshotFn = () => Promise<SnapshotData>;\n\nexport type StatefulContext<\n  State = any,\n  Context extends WorkflowContext = WorkflowContext,\n> = Context & {\n  get state(): State;\n  snapshot: SnapshotFn;\n};\n\nexport type StatefulHandleFn<State> = <\n  AcceptEvents extends WorkflowEvent<any>[],\n  Result extends ReturnType<WorkflowEvent<any>[\"with\"]> | void,\n>(\n  accept: AcceptEvents,\n  handler: Handler<AcceptEvents, Result, StatefulContext<State>>,\n) => void;\n\nexport type ResumeFunction<State> = (\n  serializable: Omit<SnapshotData, \"unrecoverableQueue\">,\n) => StatefulContext<State>;\n\nexport type WorkflowWithState<State, Input> = Input extends void | undefined\n  ? <Workflow extends WorkflowCore>(\n      workflow: Workflow,\n    ) => Omit<Workflow, \"createContext\" | \"handle\"> & {\n      createContext(): StatefulContext<State>;\n      handle: StatefulHandleFn<State>;\n      resume: ResumeFunction<State>;\n    }\n  : <Workflow extends WorkflowCore>(\n      workflow: Workflow,\n    ) => Omit<Workflow, \"createContext\" | \"handle\"> & {\n      createContext(input: Input): StatefulContext<State>;\n      handle: StatefulHandleFn<State>;\n      resume: ResumeFunction<State>;\n    };\n\ntype CreateState<State, Input, Context extends WorkflowContext> = {\n  /**\n   * @deprecated Use the context parameter directly from workflow handlers instead.\n   * The context passed to handlers already includes all state properties.\n   *\n   * @example\n   * ```ts\n   * workflow.handle([startEvent], (context, event) => {\n   *   const { sendEvent } = context;\n   *   sendEvent(processEvent.with());\n   * });\n   * ```\n   */\n  getContext(): StatefulContext<State, Context>;\n  withState: WorkflowWithState<State, Input>;\n};\n\ntype InitFunc<Input, State> = (input: Input) => State;\n\n/**\n * Creates a stateful middleware that adds state management capabilities to workflows.\n *\n * The stateful middleware allows workflows to maintain persistent state across handler executions,\n * with support for snapshots and resuming workflow execution from saved states.\n *\n * @typeParam State - The type of state object to maintain\n * @typeParam Input - The type of input used to initialize the state (defaults to void)\n * @typeParam Context - The workflow context type (defaults to WorkflowContext)\n *\n * @param init - Optional initialization function that creates the initial state from input\n * @returns A middleware object with state management capabilities\n *\n * @example\n * ```typescript\n * import { createWorkflow, workflowEvent } from \"@llamaindex/workflow-core\";\n * import { createStatefulMiddleware } from \"@llamaindex/workflow-core/middleware/state\";\n *\n * // Define your state type\n * type MyState = {\n *   counter: number;\n *   messages: string[];\n * };\n *\n * // Create the stateful middleware\n * const stateful = createStatefulMiddleware<MyState>();\n * const workflow = stateful.withState(createWorkflow());\n *\n * // Use state in handlers\n * workflow.handle([inputEvent], async (context, event) => {\n *   const { state, sendEvent } = context;\n *   state.counter += 1;\n *   state.messages.push(`Processed: ${event.data}`);\n *   sendEvent(outputEvent.with({ count: state.counter }));\n * });\n *\n * // Initialize with state\n * const { sendEvent, snapshot } = workflow.createContext({\n *   counter: 0,\n *   messages: []\n * });\n * ```\n *\n * @category Middleware\n * @public\n */\nexport function createStatefulMiddleware<\n  State,\n  Input = void,\n  Context extends WorkflowContext = WorkflowContext,\n>(init?: InitFunc<Input, State>): CreateState<State, Input, Context> {\n  return {\n    getContext: getContext as never,\n    withState: ((workflow: Workflow) => {\n      const pendingRequestSetMap = new WeakMap<\n        WorkflowContext,\n        Set<PromiseLike<unknown>>\n      >();\n      const getPendingRequestSet = (context: WorkflowContext) => {\n        if (!pendingRequestSetMap.has(context)) {\n          pendingRequestSetMap.set(context, new Set());\n        }\n        return pendingRequestSetMap.get(context)!;\n      };\n      const stableHash = createStableHash();\n      /**\n       * This is to indicate the version of the snapshot\n       *\n       * It happens when you modify the workflow, all old snapshots should be invalidated\n       */\n      // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n      const versionObj: [number[], Function][] = [];\n      const getVersion = () => stableHash(versionObj);\n\n      const registeredEvents = new Set<WorkflowEvent<any>>();\n      const isContextLockedWeakMap = new WeakMap<WorkflowContext, boolean>();\n      const isContextLocked = (context: WorkflowContext): boolean => {\n        return isContextLockedWeakMap.get(context) === true;\n      };\n      const isContextSnapshotReadyWeakSet = new WeakSet<WorkflowContext>();\n      const isContextSnapshotReady = (context: WorkflowContext) => {\n        return isContextSnapshotReadyWeakSet.has(context);\n      };\n\n      const contextEventQueueWeakMap = new WeakMap<\n        WorkflowContext,\n        WorkflowEventData<any>[]\n      >();\n      const handlerContextSetWeakMap = new WeakMap<\n        WorkflowContext,\n        Set<HandlerContext>\n      >();\n      const collectedEventHandlerContextWeakMap = new WeakMap<\n        WorkflowEventData<any>,\n        Set<HandlerContext>\n      >();\n\n      const createSnapshotFn = (context: WorkflowContext): SnapshotFn => {\n        return async function snapshotHandler() {\n          if (isContextLocked(context)) {\n            throw new Error(\n              \"Context is already locked, you cannot snapshot a same context twice\",\n            );\n          }\n          isContextLockedWeakMap.set(context, true);\n\n          // 1. wait for all context is ready\n          const handlerContexts = handlerContextSetWeakMap.get(context)!;\n\n          await Promise.all(\n            [...handlerContexts]\n              .filter((context) => context.async)\n              .map((context) => context.pending),\n          );\n          // 2. collect all necessary data for a snapshot after lock\n          const queue = contextEventQueueWeakMap.get(context)!;\n\n          // 3. serialize the data\n          isContextSnapshotReadyWeakSet.add(context);\n\n          const serializable: SnapshotData = {\n            queue: queue\n              .filter((event) => eventCounterWeakMap.has(eventSource(event)!))\n              .map((event) => [\n                event.data,\n                getEventCounter(eventSource(event)!),\n              ]),\n            unrecoverableQueue: queue\n              .filter((event) => !eventCounterWeakMap.has(eventSource(event)!))\n              .map((event) => event.data),\n            version: getVersion(),\n            state: (context as any).state\n              ? JSON.stringify((context as any).state)\n              : undefined,\n          };\n          return serializable;\n        };\n      };\n\n      let counter = 0;\n      const eventCounterWeakMap = new WeakMap<WorkflowEvent<any>, number>();\n      const counterEventMap = new Map<number, WorkflowEvent<any>>();\n      const getEventCounter = (event: WorkflowEvent<any>) => {\n        if (!eventCounterWeakMap.has(event)) {\n          eventCounterWeakMap.set(event, counter++);\n        }\n        return eventCounterWeakMap.get(event)!;\n      };\n      const getCounterEvent = (counter: number) => {\n        if (!counterEventMap.has(counter)) {\n          throw new Error(`event counter ${counter} not found`);\n        }\n        return counterEventMap.get(counter)!;\n      };\n\n      function initContext(context: WorkflowContext) {\n        handlerContextSetWeakMap.set(context, new Set());\n        contextEventQueueWeakMap.set(context, []);\n        context.__internal__call_send_event.subscribe(\n          (eventData, handlerContext) => {\n            contextEventQueueWeakMap.get(context)!.push(eventData);\n            if (isContextLocked(context)) {\n              if (isContextSnapshotReady(context)) {\n                console.warn(\n                  \"snapshot is already ready, sendEvent after snapshot is not allowed\",\n                );\n              }\n              if (!collectedEventHandlerContextWeakMap.has(eventData)) {\n                collectedEventHandlerContextWeakMap.set(eventData, new Set());\n              }\n              collectedEventHandlerContextWeakMap\n                .get(eventData)!\n                .add(handlerContext);\n            }\n          },\n        );\n        context.__internal__call_context.subscribe((handlerContext, next) => {\n          if (isContextLocked(context)) {\n            // replace it with noop, avoid calling the handler after snapshot\n            handlerContext.handler = () => {};\n            next(handlerContext);\n          } else {\n            const queue = contextEventQueueWeakMap.get(context)!;\n            handlerContext.inputs.forEach((input) => {\n              queue.splice(queue.indexOf(input), 1);\n            });\n            const originalHandler = handlerContext.handler;\n            const pendingRequests = getPendingRequestSet(context);\n            const isPendingTask = pendingRequests.size !== 0;\n            if (isPendingTask) {\n              handlerContext.handler = async (...events) => {\n                return Promise.all([...pendingRequests]).finally(() => {\n                  return originalHandler(...events);\n                });\n              };\n            }\n            handlerContextSetWeakMap.get(context)!.add(handlerContext);\n            next(handlerContext);\n          }\n        });\n      }\n\n      // Create a function to generate stream transform wrappers\n      // Shared function to create stateful context\n      const createStatefulContext = (state: State): StatefulContext<State> => {\n        const context = workflow.createContext();\n        initContext(context);\n\n        const snapshotFn = createSnapshotFn(context);\n\n        extendContext(context, {\n          get state() {\n            return state;\n          },\n          snapshot: snapshotFn,\n        });\n\n        return context as StatefulContext<State>;\n      };\n\n      return {\n        ...workflow,\n        handle: (events: WorkflowEvent<any>[], handler: any) => {\n          // version the snapshot based on the input events and function\n          // I assume `uniqueId` is changeable\n          versionObj.push([events.map(getEventCounter), handler]);\n\n          events.forEach((event) => {\n            counterEventMap.set(getEventCounter(event), event);\n          });\n\n          events.forEach((event) => {\n            registeredEvents.add(event);\n          });\n          return workflow.handle(events, handler);\n        },\n        resume(\n          serializable: Omit<SnapshotData, \"unrecoverableQueue\">,\n        ): StatefulContext<State> {\n          const resumedState = serializable.state\n            ? JSON.parse(serializable.state)\n            : undefined;\n\n          // Call the stateful createContext with the resumed state\n          const context = createStatefulContext(resumedState);\n\n          // triggers the lazy initialization of the stream wrapper\n          // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n          context.stream;\n\n          context.sendEvent(\n            ...serializable.queue.map(([data, id]) => {\n              const event = getCounterEvent(id);\n              return event.with(data);\n            }),\n          );\n\n          return context;\n        },\n        createContext(input?: Input): StatefulContext<State> {\n          const state = init?.(input as Input) as State;\n          return createStatefulContext(state);\n        },\n      };\n    }) as WorkflowWithState<State, Input>,\n  };\n}\n"],"mappings":"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"}