{"version":3,"file":"base.cjs","names":["EmptyChannelError"],"sources":["../../src/channels/base.ts"],"sourcesContent":["import {\n  ReadonlyCheckpoint,\n  uuid6,\n  Checkpoint,\n} from \"@langchain/langgraph-checkpoint\";\nimport { EmptyChannelError } from \"../errors.js\";\n\nexport function isBaseChannel(obj: unknown): obj is BaseChannel {\n  return obj != null && (obj as BaseChannel).lg_is_channel === true;\n}\n\n/** @internal */\nexport abstract class BaseChannel<\n  ValueType = unknown,\n  UpdateType = unknown,\n  CheckpointType = unknown,\n> {\n  ValueType: ValueType;\n\n  UpdateType: UpdateType;\n\n  /**\n   * The name of the channel.\n   */\n  abstract lc_graph_name: string;\n\n  /** @ignore */\n  lg_is_channel = true;\n\n  /**\n   * Return a new identical channel, optionally initialized from a checkpoint.\n   * Can be thought of as a \"restoration\" from a checkpoint which is a \"snapshot\" of the channel's state.\n   *\n   * @param {CheckpointType | undefined} checkpoint\n   * @param {CheckpointType | undefined} initialValue\n   * @returns {this}\n   */\n  abstract fromCheckpoint(checkpoint?: CheckpointType): this;\n\n  /**\n   * Update the channel's value with the given sequence of updates.\n   * The order of the updates in the sequence is arbitrary.\n   * This method is called by Pregel for all channels at the end of each step.\n   * If there are no updates, it is called with an empty sequence.\n   *\n   * Raises InvalidUpdateError if the sequence of updates is invalid.\n   * Returns True if the channel was updated, False otherwise.\n   *\n   * @throws {InvalidUpdateError} if the sequence of updates is invalid.\n   * @param {Array<UpdateType>} values\n   * @returns {void}\n   */\n  abstract update(values: UpdateType[]): boolean;\n\n  /**\n   * Return the current value of the channel.\n   *\n   * @throws {EmptyChannelError} if the channel is empty (never updated yet).\n   * @returns {ValueType}\n   */\n  abstract get(): ValueType;\n\n  /**\n   * Return a string representation of the channel's current state.\n   *\n   * @throws {EmptyChannelError} if the channel is empty (never updated yet), or doesn't support checkpoints.\n   * @returns {CheckpointType | undefined}\n   */\n  abstract checkpoint(): CheckpointType | undefined;\n\n  /**\n   * Mark the current value of the channel as consumed. By default, no-op.\n   * A channel can use this method to modify its state, preventing the value\n   * from being consumed again.\n   *\n   * Returns True if the channel was updated, False otherwise.\n   */\n  consume(): boolean {\n    return false;\n  }\n\n  /**\n   * Notify the channel that the Pregel run is finishing. By default, no-op.\n   * A channel can use this method to modify its state, preventing finish.\n   *\n   * Returns True if the channel was updated, False otherwise.\n   */\n  finish(): boolean {\n    return false;\n  }\n\n  /**\n   * Return True if the channel is available (not empty), False otherwise.\n   * Subclasses should override this method to provide a more efficient\n   * implementation than calling get() and catching EmptyChannelError.\n   */\n  isAvailable(): boolean {\n    try {\n      this.get();\n      return true;\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    } catch (error: any) {\n      if (error.name === EmptyChannelError.unminifiable_name) {\n        return false;\n      }\n      throw error;\n    }\n  }\n\n  /**\n   * Compare this channel with another channel for equality.\n   * Used to determine if two channels with the same key are semantically equivalent.\n   * Subclasses should override this method to provide a meaningful comparison.\n   *\n   * @param {BaseChannel} other - The other channel to compare with.\n   * @returns {boolean} True if the channels are equal, false otherwise.\n   */\n  equals(other: BaseChannel): boolean {\n    return this === other;\n  }\n}\n\nconst IS_ONLY_BASE_CHANNEL = Symbol.for(\"LG_IS_ONLY_BASE_CHANNEL\");\nexport function getOnlyChannels(\n  channels: Record<string, BaseChannel>\n): Record<string, BaseChannel> {\n  // @ts-expect-error - we know it's a record of base channels\n  if (channels[IS_ONLY_BASE_CHANNEL] === true) return channels;\n\n  const newChannels = {} as Record<string, BaseChannel>;\n  for (const k in channels) {\n    if (!Object.prototype.hasOwnProperty.call(channels, k)) continue;\n    const value = channels[k];\n    if (isBaseChannel(value)) newChannels[k] = value;\n  }\n\n  Object.assign(newChannels, { [IS_ONLY_BASE_CHANNEL]: true });\n  return newChannels;\n}\n\nexport function emptyChannels<Cc extends Record<string, BaseChannel>>(\n  channels: Cc,\n  checkpoint: ReadonlyCheckpoint\n): Cc {\n  const filteredChannels = getOnlyChannels(channels) as Cc;\n\n  const newChannels = {} as Cc;\n  for (const k in filteredChannels) {\n    if (!Object.prototype.hasOwnProperty.call(filteredChannels, k)) continue;\n    const channelValue = checkpoint.channel_values[k];\n    newChannels[k] = filteredChannels[k].fromCheckpoint(channelValue);\n  }\n  Object.assign(newChannels, { [IS_ONLY_BASE_CHANNEL]: true });\n  return newChannels;\n}\n\nexport function createCheckpoint<ValueType>(\n  checkpoint: ReadonlyCheckpoint,\n  channels: Record<string, BaseChannel<ValueType>> | undefined,\n  step: number,\n  options?: { id?: string }\n): Checkpoint {\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  let values: Record<string, any>;\n  if (channels === undefined) {\n    values = checkpoint.channel_values;\n  } else {\n    values = {};\n    for (const k in channels) {\n      if (!Object.prototype.hasOwnProperty.call(channels, k)) continue;\n      try {\n        values[k] = channels[k].checkpoint();\n        // eslint-disable-next-line @typescript-eslint/no-explicit-any\n      } catch (error: any) {\n        if (error.name === EmptyChannelError.unminifiable_name) {\n          // no-op\n        } else {\n          throw error; // Rethrow unexpected errors\n        }\n      }\n    }\n  }\n\n  return {\n    v: 4,\n    id: options?.id ?? uuid6(step),\n    ts: new Date().toISOString(),\n    channel_values: values,\n    channel_versions: checkpoint.channel_versions,\n    versions_seen: checkpoint.versions_seen,\n  };\n}\n"],"mappings":";;;AAOA,SAAgB,cAAc,KAAkC;AAC9D,QAAO,OAAO,QAAS,IAAoB,kBAAkB;;;AAI/D,IAAsB,cAAtB,MAIE;CACA;CAEA;;CAQA,gBAAgB;;;;;;;;CAkDhB,UAAmB;AACjB,SAAO;;;;;;;;CAST,SAAkB;AAChB,SAAO;;;;;;;CAQT,cAAuB;AACrB,MAAI;AACF,QAAK,KAAK;AACV,UAAO;WAEA,OAAY;AACnB,OAAI,MAAM,SAASA,eAAAA,kBAAkB,kBACnC,QAAO;AAET,SAAM;;;;;;;;;;;CAYV,OAAO,OAA6B;AAClC,SAAO,SAAS;;;AAIpB,MAAM,uBAAuB,OAAO,IAAI,0BAA0B;AAClE,SAAgB,gBACd,UAC6B;AAE7B,KAAI,SAAS,0BAA0B,KAAM,QAAO;CAEpD,MAAM,cAAc,EAAE;AACtB,MAAK,MAAM,KAAK,UAAU;AACxB,MAAI,CAAC,OAAO,UAAU,eAAe,KAAK,UAAU,EAAE,CAAE;EACxD,MAAM,QAAQ,SAAS;AACvB,MAAI,cAAc,MAAM,CAAE,aAAY,KAAK;;AAG7C,QAAO,OAAO,aAAa,GAAG,uBAAuB,MAAM,CAAC;AAC5D,QAAO;;AAGT,SAAgB,cACd,UACA,YACI;CACJ,MAAM,mBAAmB,gBAAgB,SAAS;CAElD,MAAM,cAAc,EAAE;AACtB,MAAK,MAAM,KAAK,kBAAkB;AAChC,MAAI,CAAC,OAAO,UAAU,eAAe,KAAK,kBAAkB,EAAE,CAAE;EAChE,MAAM,eAAe,WAAW,eAAe;AAC/C,cAAY,KAAK,iBAAiB,GAAG,eAAe,aAAa;;AAEnE,QAAO,OAAO,aAAa,GAAG,uBAAuB,MAAM,CAAC;AAC5D,QAAO;;AAGT,SAAgB,iBACd,YACA,UACA,MACA,SACY;CAEZ,IAAI;AACJ,KAAI,aAAa,KAAA,EACf,UAAS,WAAW;MACf;AACL,WAAS,EAAE;AACX,OAAK,MAAM,KAAK,UAAU;AACxB,OAAI,CAAC,OAAO,UAAU,eAAe,KAAK,UAAU,EAAE,CAAE;AACxD,OAAI;AACF,WAAO,KAAK,SAAS,GAAG,YAAY;YAE7B,OAAY;AACnB,QAAI,MAAM,SAASA,eAAAA,kBAAkB,mBAAmB,OAGtD,OAAM;;;;AAMd,QAAO;EACL,GAAG;EACH,IAAI,SAAS,OAAA,GAAA,gCAAA,OAAY,KAAK;EAC9B,qBAAI,IAAI,MAAM,EAAC,aAAa;EAC5B,gBAAgB;EAChB,kBAAkB,WAAW;EAC7B,eAAe,WAAW;EAC3B"}