@langchain/langgraph-sdk
Version:
Client library for interacting with the LangGraph API
1 lines • 4.98 kB
Source Map (JSON)
{"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"}