{"version":3,"file":"namespace.cjs","names":[],"sources":["../../src/utils/namespace.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\n\n/**\n * A constructor type that can be used as a base class for branding.\n */\ntype Constructor = abstract new (...args: any[]) => any;\n\n/**\n * The return type of `Namespace.brand()`: the original base class\n * intersected with a polymorphic `isInstance` type guard.\n */\ntype BrandedClass<TBase extends Constructor> = TBase & {\n  isInstance: IsInstanceFn;\n};\n\n/**\n * A static `isInstance` type guard that resolves to the subclass it's\n * called on via the generic `this` parameter.\n *\n * At call sites TypeScript infers `T` from the class, so\n * `StandardError.isInstance(obj)` narrows `obj` to `StandardError`.\n */\ntype IsInstanceFn = <T extends Constructor>(\n  this: T,\n  obj: unknown\n) => obj is InstanceType<T>;\n\n/**\n * A namespace object for hierarchical symbol-based branding.\n *\n * Namespaces are internal authoring tools. They are not intended to be\n * part of the public API -- only the branded classes are.\n *\n * @example\n * ```typescript\n * const langchain = createNamespace(\"langchain\");\n * const errorNs = langchain.sub(\"error\");\n *\n * export class LangChainError extends errorNs.brand(Error) {\n *   readonly name = \"LangChainError\";\n * }\n *\n * export class ModelAbortError extends errorNs.brand(LangChainError, \"model-abort\") {\n *   readonly name = \"ModelAbortError\";\n * }\n * ```\n */\nexport interface Namespace {\n  /**\n   * Brand a base class with this namespace's symbols.\n   *\n   * Without a marker, creates a namespace-level base class whose\n   * `static isInstance` checks for the namespace's own symbol.\n   *\n   * With a marker, creates a leaf class whose `static isInstance`\n   * checks for the marker-specific symbol.\n   *\n   * @param Base - The base class to extend\n   * @param marker - Optional marker for leaf classes\n   * @returns A new class extending Base with symbol branding and static isInstance\n   */\n  brand<TBase extends Constructor>(\n    Base: TBase,\n    marker?: string\n  ): BrandedClass<TBase>;\n\n  /**\n   * Create a child namespace.\n   *\n   * @param childPath - The child segment to append to the current path\n   * @returns A new Namespace with the extended path\n   */\n  sub(childPath: string): Namespace;\n\n  /**\n   * Check if an object is branded under this namespace (at any level).\n   *\n   * @param obj - The object to check\n   * @returns true if the object carries this namespace's symbol\n   */\n  isInstance(obj: unknown): boolean;\n}\n\n/**\n * Create a symbol-based namespace for hierarchical `isInstance` checking.\n *\n * Each namespace level gets its own `Symbol.for(path)`. When a class is\n * branded via `.brand()`, only the new symbol for that level is stamped\n * on the prototype. Parent symbols are inherited implicitly through the\n * class extension chain -- `symbol in obj` traverses the prototype chain,\n * so a `ConfigError` instance is recognized by `LangChainError.isInstance()`\n * because it extends `GoogleError` which extends `LangChainError`, whose\n * prototype already carries the `langchain.error` symbol.\n *\n * @param path - The dot-separated namespace path (e.g. \"langchain.error\")\n * @returns A Namespace object with `.brand()`, `.sub()`, and `.isInstance()`\n *\n * @example\n * ```typescript\n * const langchain = createNamespace(\"langchain\");\n * const errorNs = langchain.sub(\"error\");\n * const googleNs = errorNs.sub(\"google\");\n *\n * class LangChainError extends errorNs.brand(Error) {}\n * class GoogleError extends googleNs.brand(LangChainError) {}\n * class ConfigError extends googleNs.brand(GoogleError, \"configuration\") {}\n *\n * const err = new ConfigError(\"bad config\");\n * LangChainError.isInstance(err); // true (checks langchain.error symbol)\n * GoogleError.isInstance(err);    // true (checks langchain.error.google symbol)\n * ConfigError.isInstance(err);    // true (checks langchain.error.google.configuration symbol)\n * ```\n */\nexport function createNamespace(path: string): Namespace {\n  const symbol: symbol = Symbol.for(path);\n\n  return {\n    brand<TBase extends Constructor>(Base: TBase, marker?: string) {\n      const brandSymbol: symbol = marker\n        ? Symbol.for(`${path}.${marker}`)\n        : symbol;\n\n      class _Branded extends (Base as any) {\n        readonly [brandSymbol] = true as const;\n\n        constructor(...args: any[]) {\n          super(...args);\n        }\n\n        static isInstance(obj: unknown): boolean {\n          return (\n            typeof obj === \"object\" &&\n            obj !== null &&\n            brandSymbol in obj &&\n            (obj as Record<symbol, unknown>)[brandSymbol] === true\n          );\n        }\n      }\n\n      // Inherit the base class's name so \"_Branded\" doesn't leak\n      // through the static prototype chain.\n      Object.defineProperty(_Branded, \"name\", { value: Base.name });\n\n      return _Branded as unknown as BrandedClass<TBase>;\n    },\n\n    sub(childPath: string): Namespace {\n      return createNamespace(`${path}.${childPath}`);\n    },\n\n    isInstance(obj: unknown): boolean {\n      return (\n        typeof obj === \"object\" &&\n        obj !== null &&\n        symbol in obj &&\n        (obj as Record<symbol, unknown>)[symbol] === true\n      );\n    },\n  };\n}\n\n/** Base namespace used throughout LangChain */\nexport const ns = createNamespace(\"langchain\");\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiHA,SAAgB,gBAAgB,MAAyB;CACvD,MAAM,SAAiB,OAAO,IAAI,KAAK;AAEvC,QAAO;EACL,MAAiC,MAAa,QAAiB;GAC7D,MAAM,cAAsB,SACxB,OAAO,IAAI,GAAG,KAAK,GAAG,SAAS,GAC/B;GAEJ,MAAM,iBAAkB,KAAa;IACnC,CAAU,eAAe;IAEzB,YAAY,GAAG,MAAa;AAC1B,WAAM,GAAG,KAAK;;IAGhB,OAAO,WAAW,KAAuB;AACvC,YACE,OAAO,QAAQ,YACf,QAAQ,QACR,eAAe,OACd,IAAgC,iBAAiB;;;AAOxD,UAAO,eAAe,UAAU,QAAQ,EAAE,OAAO,KAAK,MAAM,CAAC;AAE7D,UAAO;;EAGT,IAAI,WAA8B;AAChC,UAAO,gBAAgB,GAAG,KAAK,GAAG,YAAY;;EAGhD,WAAW,KAAuB;AAChC,UACE,OAAO,QAAQ,YACf,QAAQ,QACR,UAAU,OACT,IAAgC,YAAY;;EAGlD;;;AAIH,MAAa,KAAK,gBAAgB,YAAY"}