{"version":3,"file":"snapshot.cjs","names":["arg: any","index: any","event: WorkflowEvent<T>","reason?: any","workflow: Workflow","context: WorkflowContext","versionObj: [number[], Function][]","context","serializable: SnapshotData","event: WorkflowEvent<any>","counter: number","counter","events: WorkflowEvent<any>[]","handler: any","data: any[]","serializable: Omit<SnapshotData, \"unrecoverableQueue\">","data","lazyInitStream: WorkflowStream | null","callback: (reason: any) => void | Promise<void>","isPromiseLike"],"sources":["../src/middleware/snapshot/stable-hash.ts","../src/middleware/snapshot.ts"],"sourcesContent":["// 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  type Workflow as WorkflowCore,\n  type WorkflowContext,\n  type WorkflowEvent,\n  workflowEvent,\n  type WorkflowEventData,\n  WorkflowStream,\n} from \"@llama-flow/core\";\nimport type { HandlerContext } from \"../core/context\";\nimport { createStableHash } from \"./snapshot/stable-hash\";\nimport { createSubscribable, isPromiseLike } from \"../core/utils\";\n\n/**\n * @internal We don't want to expose this special event to the user\n */\nconst snapshotEvent = workflowEvent<WorkflowEvent<any>>();\nconst reasonWeakMap = new WeakMap<WorkflowEventData<any>, any>();\n\nconst noop = () => {};\n\nexport const request = <T>(\n  event: WorkflowEvent<T>,\n  reason?: any,\n): WorkflowEventData<WorkflowEvent<T>> => {\n  const ev = snapshotEvent.with(event);\n  reasonWeakMap.set(ev, reason);\n  return ev;\n};\n\nexport type SnapshotFn = () => Promise<\n  [requestEvents: WorkflowEvent<any>[], serializable: SnapshotData]\n>;\n\ntype SnapshotWorkflowContext<Workflow extends WorkflowCore> = ReturnType<\n  Workflow[\"createContext\"]\n> & {\n  onRequest: <Event extends WorkflowEvent<any>>(\n    event: Event,\n    callback: (reason: any) => void | Promise<void>,\n  ) => () => void;\n  /**\n   * Snapshot will lock the context and wait for there is no pending event.\n   *\n   * This is useful when you want to take a current snapshot of the workflow\n   *\n   */\n  snapshot: SnapshotFn;\n};\n\ntype WithSnapshotWorkflow<Workflow extends WorkflowCore> = Omit<\n  Workflow,\n  \"createContext\"\n> & {\n  createContext: () => SnapshotWorkflowContext<Workflow>;\n  resume: (\n    data: any[],\n    serializable: Omit<SnapshotData, \"unrecoverableQueue\">,\n  ) => SnapshotWorkflowContext<Workflow>;\n};\n\ninterface 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: [data: any, id: number][];\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  missing: number[];\n}\n\ntype OnRequestFn<Event extends WorkflowEvent<any> = WorkflowEvent<any>> = (\n  eventData: Event,\n  reason: any,\n) => void | Promise<void>;\n\nexport function withSnapshot<Workflow extends WorkflowCore>(\n  workflow: Workflow,\n): WithSnapshotWorkflow<Workflow> {\n  const requests = createSubscribable<OnRequestFn>();\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  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 collectedEvents = contextEventQueueWeakMap.get(context)!;\n      const requestEvents = collectedEvents\n        .filter((event) => snapshotEvent.include(event))\n        .map((event) => event.data);\n      // there might have pending events in the queue, we need to collect them\n      const queue = collectedEvents.filter(\n        (event) => !snapshotEvent.include(event),\n      );\n\n      // 3. serialize the data\n      isContextSnapshotReadyWeakSet.add(context);\n\n      if (requestEvents.some((event) => !registeredEvents.has(event))) {\n        console.warn(\"request event is not registered in the workflow\");\n      }\n\n      const serializable: SnapshotData = {\n        queue: queue\n          .filter((event) => eventCounterWeakMap.has(eventSource(event)!))\n          .map((event) => [event.data, getEventCounter(eventSource(event)!)]),\n        unrecoverableQueue: queue\n          .filter((event) => !eventCounterWeakMap.has(eventSource(event)!))\n          .map((event) => [event.data, getEventCounter(eventSource(event)!)]),\n        version: getVersion(),\n        missing: requestEvents\n          // if you are request an event that is not in the handler, it's meaningless (from a logic perspective)\n          .filter((event) => eventCounterWeakMap.has(event))\n          .map((event) => getEventCounter(event)),\n      };\n      return [requestEvents, 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 = noop;\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  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      data: any[],\n      serializable: Omit<SnapshotData, \"unrecoverableQueue\">,\n    ): any {\n      const events = data.map((d, i) =>\n        getCounterEvent(serializable.missing[i]!).with(d),\n      );\n      const context = workflow.createContext();\n      initContext(context);\n      const stream = context.stream;\n      context.sendEvent(\n        ...serializable.queue.map(([data, id]) => {\n          const event = getCounterEvent(id);\n          return event.with(data);\n        }),\n      );\n      context.sendEvent(...events);\n\n      let lazyInitStream: WorkflowStream | null = null;\n      const snapshotFn = createSnapshotFn(context);\n      return {\n        ...context,\n        snapshot: snapshotFn,\n        onRequest: (\n          event: WorkflowEvent<any>,\n          callback: (reason: any) => void | Promise<void>,\n        ): (() => void) =>\n          requests.subscribe((ev, reason) => {\n            if (ev === event) {\n              return callback(reason);\n            }\n          }),\n        get stream() {\n          if (!lazyInitStream) {\n            lazyInitStream = stream.pipeThrough(\n              new TransformStream({\n                transform: (event, controller) => {\n                  if (snapshotEvent.include(event)) {\n                    const data = event.data;\n                    requests.publish(data, reasonWeakMap.get(event));\n                  } else {\n                    // ignore snapshot event from stream\n                    controller.enqueue(event);\n                  }\n                },\n              }),\n            );\n          }\n          return lazyInitStream;\n        },\n      };\n    },\n    createContext(): any {\n      const context = workflow.createContext();\n      initContext(context);\n      const stream = context.stream;\n      let lazyInitStream: WorkflowStream | null = null;\n      const snapshotFn = createSnapshotFn(context);\n      return {\n        ...context,\n        snapshot: snapshotFn,\n        onRequest: (\n          event: WorkflowEvent<any>,\n          callback: (reason: any) => void | Promise<void>,\n        ): (() => void) =>\n          requests.subscribe((ev, reason) => {\n            if (ev === event) {\n              return callback(reason);\n            }\n          }),\n        get stream() {\n          if (!lazyInitStream) {\n            lazyInitStream = stream.pipeThrough(\n              new TransformStream({\n                transform: (event, controller) => {\n                  if (snapshotEvent.include(event)) {\n                    const data = event.data;\n                    const results = requests.publish(\n                      data,\n                      reasonWeakMap.get(event),\n                    );\n                    const pendingRequests = getPendingRequestSet(context);\n                    results.filter(isPromiseLike).forEach((promise) => {\n                      const task = promise.then(() => {\n                        pendingRequests.delete(task);\n                      });\n                      pendingRequests.add(task);\n                    });\n                  } else {\n                    // ignore snapshot event from stream\n                    controller.enqueue(event);\n                  }\n                },\n              }),\n            );\n          }\n          return lazyInitStream;\n        },\n      };\n    },\n  } as unknown as WithSnapshotWorkflow<Workflow>;\n}\n"],"mappings":"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"}