{"version":3,"file":"subscription.cjs","names":[],"sources":["../../../src/client/stream/subscription.ts"],"sourcesContent":["import type {\n  Channel,\n  Event,\n  Namespace,\n  SubscribeParams,\n} from \"@langchain/protocol\";\n\n/**\n * Strip dynamic suffixes (after `:`) from a namespace segment.\n *\n * Mirrors `normalize_namespace_segment` in\n * `api/langgraph_api/protocol/namespace.py`. Server-emitted namespaces\n * contain runtime-generated suffixes like `\"fetcher:abc-uuid\"`, while\n * user-supplied filters are typically static names (`\"fetcher\"`).\n */\nfunction normalizeSegment(segment: string): string {\n  const idx = segment.indexOf(\":\");\n  return idx === -1 ? segment : segment.slice(0, idx);\n}\n\n/**\n * Whether `eventNamespace` starts with `prefix`.\n *\n * Segments are compared literally first; if the prefix segment itself\n * contains no `:`, the candidate segment is also compared after its\n * dynamic suffix is stripped. This mirrors `is_prefix_match` in\n * `api/langgraph_api/protocol/namespace.py` so server-side filtering\n * and client-side per-subscription narrowing stay consistent.\n */\nfunction isPrefixMatch(eventNamespace: Namespace, prefix: Namespace): boolean {\n  if (prefix.length > eventNamespace.length) return false;\n  for (let i = 0; i < prefix.length; i += 1) {\n    const segment = prefix[i]!;\n    const candidate = eventNamespace[i]!;\n    if (candidate === segment) continue;\n    if (segment.includes(\":\")) return false;\n    if (normalizeSegment(candidate) === segment) continue;\n    return false;\n  }\n  return true;\n}\n\nfunction namespaceMatches(\n  eventNamespace: Namespace,\n  prefixes: Namespace[] | undefined,\n  depth: number | undefined\n): boolean {\n  if (!prefixes || prefixes.length === 0) {\n    return true;\n  }\n\n  return prefixes.some((prefix) => {\n    if (!isPrefixMatch(eventNamespace, prefix)) return false;\n    if (depth === undefined) return true;\n    return eventNamespace.length - prefix.length <= depth;\n  });\n}\n\n/**\n * Maps a protocol event method to its subscription channel.\n *\n * Returns `undefined` for unrecognized methods so that new server-side\n * channels (e.g. from extension transformers) don't break existing clients.\n *\n * @param event - Event whose method should be mapped to a channel.\n */\nexport function inferChannel(event: Event): Channel | undefined {\n  switch (event.method) {\n    case \"values\":\n      return \"values\";\n    case \"checkpoints\":\n      return \"checkpoints\";\n    case \"updates\":\n      return \"updates\";\n    case \"messages\":\n      return \"messages\";\n    case \"tools\":\n      return \"tools\";\n    case \"custom\": {\n      const data = event.params.data as { name?: string } | undefined;\n      return data?.name != null ? `custom:${data.name}` : \"custom\";\n    }\n    case \"lifecycle\":\n      return \"lifecycle\";\n    case \"input.requested\":\n      return \"input\";\n    case \"tasks\":\n      return \"tasks\";\n    default:\n      return undefined;\n  }\n}\n\n/**\n * Returns whether an event should be delivered for a subscription definition.\n *\n * @param event - Event being checked for delivery.\n * @param definition - Subscription filter definition to evaluate against.\n */\nexport function matchesSubscription(\n  event: Event,\n  definition: SubscribeParams\n): boolean {\n  const channel = inferChannel(event);\n  if (channel === undefined) return false;\n\n  const channels = definition.channels as Channel[];\n  const channelMatched =\n    channels.includes(channel) ||\n    (channel.startsWith(\"custom:\") && channels.includes(\"custom\"));\n  if (!channelMatched) {\n    return false;\n  }\n\n  return namespaceMatches(\n    event.params.namespace,\n    definition.namespaces,\n    definition.depth\n  );\n}\n"],"mappings":";;;;;;;;;AAeA,SAAS,iBAAiB,SAAyB;CACjD,MAAM,MAAM,QAAQ,QAAQ,IAAI;AAChC,QAAO,QAAQ,KAAK,UAAU,QAAQ,MAAM,GAAG,IAAI;;;;;;;;;;;AAYrD,SAAS,cAAc,gBAA2B,QAA4B;AAC5E,KAAI,OAAO,SAAS,eAAe,OAAQ,QAAO;AAClD,MAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK,GAAG;EACzC,MAAM,UAAU,OAAO;EACvB,MAAM,YAAY,eAAe;AACjC,MAAI,cAAc,QAAS;AAC3B,MAAI,QAAQ,SAAS,IAAI,CAAE,QAAO;AAClC,MAAI,iBAAiB,UAAU,KAAK,QAAS;AAC7C,SAAO;;AAET,QAAO;;AAGT,SAAS,iBACP,gBACA,UACA,OACS;AACT,KAAI,CAAC,YAAY,SAAS,WAAW,EACnC,QAAO;AAGT,QAAO,SAAS,MAAM,WAAW;AAC/B,MAAI,CAAC,cAAc,gBAAgB,OAAO,CAAE,QAAO;AACnD,MAAI,UAAU,KAAA,EAAW,QAAO;AAChC,SAAO,eAAe,SAAS,OAAO,UAAU;GAChD;;;;;;;;;;AAWJ,SAAgB,aAAa,OAAmC;AAC9D,SAAQ,MAAM,QAAd;EACE,KAAK,SACH,QAAO;EACT,KAAK,cACH,QAAO;EACT,KAAK,UACH,QAAO;EACT,KAAK,WACH,QAAO;EACT,KAAK,QACH,QAAO;EACT,KAAK,UAAU;GACb,MAAM,OAAO,MAAM,OAAO;AAC1B,UAAO,MAAM,QAAQ,OAAO,UAAU,KAAK,SAAS;;EAEtD,KAAK,YACH,QAAO;EACT,KAAK,kBACH,QAAO;EACT,KAAK,QACH,QAAO;EACT,QACE;;;;;;;;;AAUN,SAAgB,oBACd,OACA,YACS;CACT,MAAM,UAAU,aAAa,MAAM;AACnC,KAAI,YAAY,KAAA,EAAW,QAAO;CAElC,MAAM,WAAW,WAAW;AAI5B,KAAI,EAFF,SAAS,SAAS,QAAQ,IACzB,QAAQ,WAAW,UAAU,IAAI,SAAS,SAAS,SAAS,EAE7D,QAAO;AAGT,QAAO,iBACL,MAAM,OAAO,WACb,WAAW,YACX,WAAW,MACZ"}