{"version":3,"file":"runtime.cjs","names":[],"sources":["../../../src/stream/projections/runtime.ts"],"sourcesContent":["import type { Channel, Event } from \"@langchain/protocol\";\nimport type { SubscriptionHandle } from \"../../client/stream/index.js\";\nimport type { ProjectionRuntime, ThreadStream } from \"../types.js\";\n\ninterface ProjectionSubscriptionOptions {\n  thread: ThreadStream;\n  channels: readonly Channel[];\n  namespace: readonly string[];\n  depth?: number;\n  /**\n   * Some transports pause a subscription between runs. Most projections\n   * intentionally preserve their historical one-pass behavior; opt in when\n   * the projection already handled resume loops.\n   */\n  resumeOnPause?: boolean;\n  onSubscribe?: () => void;\n  onEvent(event: Event): void;\n  onFinally?: () => void;\n}\n\n/**\n * Shared async subscription lifecycle for projection runtimes.\n */\nexport function openProjectionSubscription({\n  thread,\n  channels,\n  namespace,\n  depth = 1,\n  resumeOnPause = false,\n  onSubscribe,\n  onEvent,\n  onFinally,\n}: ProjectionSubscriptionOptions): ProjectionRuntime {\n  let handle: SubscriptionHandle<Event> | undefined;\n  let disposed = false;\n\n  const start = async () => {\n    try {\n      const subscribeParams = {\n        channels: [...channels],\n        namespaces:\n          namespace.length > 0\n            ? ([[...namespace]] as string[][])\n            : ([[]] as string[][]),\n        depth,\n      };\n      const subscription = await thread.subscribe(subscribeParams);\n      handle = subscription;\n      if (disposed) {\n        await subscription.unsubscribe();\n        return;\n      }\n      onSubscribe?.();\n\n      do {\n        for await (const event of subscription) {\n          if (disposed) break;\n          onEvent(event);\n        }\n        if (disposed || !resumeOnPause || !subscription.isPaused) break;\n        await subscription.waitForResume();\n      } while (!disposed);\n    } catch {\n      // Thread closed / errored; projections expose their last good snapshot.\n    } finally {\n      onFinally?.();\n    }\n  };\n\n  void start();\n\n  return {\n    async dispose() {\n      disposed = true;\n      try {\n        await handle?.unsubscribe();\n      } catch {\n        // already closed\n      }\n    },\n  };\n}\n"],"mappings":";;;;AAuBA,SAAgB,2BAA2B,EACzC,QACA,UACA,WACA,QAAQ,GACR,gBAAgB,OAChB,aACA,SACA,aACmD;CACnD,IAAI;CACJ,IAAI,WAAW;CAEf,MAAM,QAAQ,YAAY;AACxB,MAAI;GACF,MAAM,kBAAkB;IACtB,UAAU,CAAC,GAAG,SAAS;IACvB,YACE,UAAU,SAAS,IACd,CAAC,CAAC,GAAG,UAAU,CAAC,GAChB,CAAC,EAAE,CAAC;IACX;IACD;GACD,MAAM,eAAe,MAAM,OAAO,UAAU,gBAAgB;AAC5D,YAAS;AACT,OAAI,UAAU;AACZ,UAAM,aAAa,aAAa;AAChC;;AAEF,kBAAe;AAEf,MAAG;AACD,eAAW,MAAM,SAAS,cAAc;AACtC,SAAI,SAAU;AACd,aAAQ,MAAM;;AAEhB,QAAI,YAAY,CAAC,iBAAiB,CAAC,aAAa,SAAU;AAC1D,UAAM,aAAa,eAAe;YAC3B,CAAC;UACJ,WAEE;AACR,gBAAa;;;AAIZ,QAAO;AAEZ,QAAO,EACL,MAAM,UAAU;AACd,aAAW;AACX,MAAI;AACF,SAAM,QAAQ,aAAa;UACrB;IAIX"}