{"version":3,"file":"dynamic_barrier_value.cjs","names":["BaseChannel","InvalidUpdateError","areSetsEqual","EmptyChannelError"],"sources":["../../src/channels/dynamic_barrier_value.ts"],"sourcesContent":["import { EmptyChannelError, InvalidUpdateError } from \"../errors.js\";\nimport { BaseChannel } from \"./base.js\";\nimport { areSetsEqual } from \"./named_barrier_value.js\";\n\nexport interface WaitForNames<Value> {\n  __names: Value[];\n}\n\nfunction isWaitForNames<Value>(\n  v: WaitForNames<Value> | Value\n): v is WaitForNames<Value> {\n  return (v as WaitForNames<Value>).__names !== undefined;\n}\n\n/**\n * A channel that switches between two states\n *\n * - in the \"priming\" state it can't be read from.\n *     - if it receives a WaitForNames update, it switches to the \"waiting\" state.\n * - in the \"waiting\" state it collects named values until all are received.\n *     - once all named values are received, it can be read once, and it switches\n *       back to the \"priming\" state.\n */\nexport class DynamicBarrierValue<Value> extends BaseChannel<\n  void,\n  Value | WaitForNames<Value>,\n  [Value[] | undefined, Value[]]\n> {\n  lc_graph_name = \"DynamicBarrierValue\";\n\n  names?: Set<Value>; // Names of nodes that we want to wait for.\n\n  seen: Set<Value>;\n\n  constructor() {\n    super();\n    this.names = undefined;\n    this.seen = new Set<Value>();\n  }\n\n  fromCheckpoint(checkpoint?: [Value[] | undefined, Value[]]) {\n    const empty = new DynamicBarrierValue<Value>();\n    if (typeof checkpoint !== \"undefined\") {\n      empty.names = new Set(checkpoint[0]);\n      empty.seen = new Set(checkpoint[1]);\n    }\n    return empty as this;\n  }\n\n  update(values: (Value | WaitForNames<Value>)[]): boolean {\n    const waitForNames = values.filter(isWaitForNames);\n    if (waitForNames.length > 0) {\n      if (waitForNames.length > 1) {\n        throw new InvalidUpdateError(\n          \"Received multiple WaitForNames updates in the same step.\"\n        );\n      }\n      this.names = new Set(waitForNames[0].__names);\n      return true;\n    } else if (this.names !== undefined) {\n      let updated = false;\n      for (const value of values) {\n        if (isWaitForNames(value)) {\n          throw new Error(\n            \"Assertion Error: Received unexpected WaitForNames instance.\"\n          );\n        }\n        if (this.names.has(value) && !this.seen.has(value)) {\n          this.seen.add(value);\n          updated = true;\n        }\n      }\n      return updated;\n    }\n    return false;\n  }\n\n  consume(): boolean {\n    if (this.seen && this.names && areSetsEqual(this.seen, this.names)) {\n      this.seen = new Set<Value>();\n      this.names = undefined;\n      return true;\n    }\n    return false;\n  }\n\n  // If we have not yet seen all the node names we want to wait for,\n  // throw an error to prevent continuing.\n  get(): void {\n    if (!this.names || !areSetsEqual(this.names, this.seen)) {\n      throw new EmptyChannelError();\n    }\n    return undefined;\n  }\n\n  checkpoint(): [Value[] | undefined, Value[]] {\n    return [this.names ? [...this.names] : undefined, [...this.seen]];\n  }\n\n  isAvailable(): boolean {\n    return !!this.names && areSetsEqual(this.names, this.seen);\n  }\n}\n\n/**\n * A channel that switches between two states with an additional finished flag\n *\n * - in the \"priming\" state it can't be read from.\n *     - if it receives a WaitForNames update, it switches to the \"waiting\" state.\n * - in the \"waiting\" state it collects named values until all are received.\n *     - once all named values are received, and the finished flag is set, it can be read once, and it switches\n *       back to the \"priming\" state.\n * @internal\n */\nexport class DynamicBarrierValueAfterFinish<Value> extends BaseChannel<\n  void,\n  Value | WaitForNames<Value>,\n  [Value[] | undefined, Value[], boolean]\n> {\n  lc_graph_name = \"DynamicBarrierValueAfterFinish\";\n\n  names?: Set<Value>; // Names of nodes that we want to wait for.\n\n  seen: Set<Value>;\n\n  finished: boolean;\n\n  constructor() {\n    super();\n    this.names = undefined;\n    this.seen = new Set<Value>();\n    this.finished = false;\n  }\n\n  fromCheckpoint(checkpoint?: [Value[] | undefined, Value[], boolean]) {\n    const empty = new DynamicBarrierValueAfterFinish<Value>();\n    if (typeof checkpoint !== \"undefined\") {\n      const [names, seen, finished] = checkpoint;\n      empty.names = names ? new Set(names) : undefined;\n      empty.seen = new Set(seen);\n      empty.finished = finished;\n    }\n    return empty as this;\n  }\n\n  update(values: (Value | WaitForNames<Value>)[]): boolean {\n    const waitForNames = values.filter(isWaitForNames);\n    if (waitForNames.length > 0) {\n      if (waitForNames.length > 1) {\n        throw new InvalidUpdateError(\n          \"Received multiple WaitForNames updates in the same step.\"\n        );\n      }\n      this.names = new Set(waitForNames[0].__names);\n      return true;\n    } else if (this.names !== undefined) {\n      let updated = false;\n      for (const value of values) {\n        if (isWaitForNames(value)) {\n          throw new Error(\n            \"Assertion Error: Received unexpected WaitForNames instance.\"\n          );\n        }\n        if (this.names.has(value) && !this.seen.has(value)) {\n          this.seen.add(value);\n          updated = true;\n        }\n      }\n      return updated;\n    }\n    return false;\n  }\n\n  consume(): boolean {\n    if (\n      this.finished &&\n      this.seen &&\n      this.names &&\n      areSetsEqual(this.seen, this.names)\n    ) {\n      this.seen = new Set<Value>();\n      this.names = undefined;\n      this.finished = false;\n      return true;\n    }\n    return false;\n  }\n\n  finish(): boolean {\n    if (!this.finished && this.names && areSetsEqual(this.names, this.seen)) {\n      this.finished = true;\n      return true;\n    }\n    return false;\n  }\n\n  get(): void {\n    if (!this.finished || !this.names || !areSetsEqual(this.names, this.seen)) {\n      throw new EmptyChannelError();\n    }\n    return undefined;\n  }\n\n  checkpoint(): [Value[] | undefined, Value[], boolean] {\n    return [\n      this.names ? [...this.names] : undefined,\n      [...this.seen],\n      this.finished,\n    ];\n  }\n\n  isAvailable(): boolean {\n    return this.finished && !!this.names && areSetsEqual(this.names, this.seen);\n  }\n}\n"],"mappings":";;;;AAQA,SAAS,eACP,GAC0B;AAC1B,QAAQ,EAA0B,YAAY,KAAA;;;;;;;;;;;AAYhD,IAAa,sBAAb,MAAa,4BAAmCA,aAAAA,YAI9C;CACA,gBAAgB;CAEhB;CAEA;CAEA,cAAc;AACZ,SAAO;AACP,OAAK,QAAQ,KAAA;AACb,OAAK,uBAAO,IAAI,KAAY;;CAG9B,eAAe,YAA6C;EAC1D,MAAM,QAAQ,IAAI,qBAA4B;AAC9C,MAAI,OAAO,eAAe,aAAa;AACrC,SAAM,QAAQ,IAAI,IAAI,WAAW,GAAG;AACpC,SAAM,OAAO,IAAI,IAAI,WAAW,GAAG;;AAErC,SAAO;;CAGT,OAAO,QAAkD;EACvD,MAAM,eAAe,OAAO,OAAO,eAAe;AAClD,MAAI,aAAa,SAAS,GAAG;AAC3B,OAAI,aAAa,SAAS,EACxB,OAAM,IAAIC,eAAAA,mBACR,2DACD;AAEH,QAAK,QAAQ,IAAI,IAAI,aAAa,GAAG,QAAQ;AAC7C,UAAO;aACE,KAAK,UAAU,KAAA,GAAW;GACnC,IAAI,UAAU;AACd,QAAK,MAAM,SAAS,QAAQ;AAC1B,QAAI,eAAe,MAAM,CACvB,OAAM,IAAI,MACR,8DACD;AAEH,QAAI,KAAK,MAAM,IAAI,MAAM,IAAI,CAAC,KAAK,KAAK,IAAI,MAAM,EAAE;AAClD,UAAK,KAAK,IAAI,MAAM;AACpB,eAAU;;;AAGd,UAAO;;AAET,SAAO;;CAGT,UAAmB;AACjB,MAAI,KAAK,QAAQ,KAAK,SAASC,4BAAAA,aAAa,KAAK,MAAM,KAAK,MAAM,EAAE;AAClE,QAAK,uBAAO,IAAI,KAAY;AAC5B,QAAK,QAAQ,KAAA;AACb,UAAO;;AAET,SAAO;;CAKT,MAAY;AACV,MAAI,CAAC,KAAK,SAAS,CAACA,4BAAAA,aAAa,KAAK,OAAO,KAAK,KAAK,CACrD,OAAM,IAAIC,eAAAA,mBAAmB;;CAKjC,aAA6C;AAC3C,SAAO,CAAC,KAAK,QAAQ,CAAC,GAAG,KAAK,MAAM,GAAG,KAAA,GAAW,CAAC,GAAG,KAAK,KAAK,CAAC;;CAGnE,cAAuB;AACrB,SAAO,CAAC,CAAC,KAAK,SAASD,4BAAAA,aAAa,KAAK,OAAO,KAAK,KAAK"}