{"version":3,"file":"data-client.cjs","names":[],"sources":["../src/data-client.ts"],"sourcesContent":["import { GetItemArgs, IndexItem, ItemData, ItemKind, ListItemsArgs, SearchDocsArgs } from './types';\n\nfunction normalizeValue(value: string) {\n  return value.trim().toLowerCase();\n}\n\nfunction clampLimit(limit: number | undefined, fallback: number, max: number) {\n  if (typeof limit !== 'number' || Number.isNaN(limit)) {\n    return fallback;\n  }\n\n  return Math.max(1, Math.min(max, Math.floor(limit)));\n}\n\nexport class MantineMcpDataClient {\n  private readonly baseUrl: string;\n  private readonly timeoutMs: number;\n  private indexCache: IndexItem[] | null = null;\n  private itemCache = new Map<string, ItemData>();\n\n  constructor(baseUrl = 'https://mantine.dev/mcp', timeoutMs = 10000) {\n    this.baseUrl = baseUrl.replace(/\\/+$/, '');\n    this.timeoutMs = timeoutMs;\n  }\n\n  private async fetchJson<T>(relativePath: string): Promise<T> {\n    const controller = new AbortController();\n    const timer = setTimeout(() => controller.abort(), this.timeoutMs);\n\n    try {\n      const url = `${this.baseUrl}/${relativePath.replace(/^\\/+/, '')}`;\n      const response = await fetch(url, { signal: controller.signal });\n\n      if (!response.ok) {\n        throw new Error(`Failed to fetch ${url}: ${response.status}`);\n      }\n\n      return (await response.json()) as T;\n    } finally {\n      clearTimeout(timer);\n    }\n  }\n\n  async getIndex() {\n    if (this.indexCache) {\n      return this.indexCache;\n    }\n\n    this.indexCache = await this.fetchJson<IndexItem[]>('index.json');\n    return this.indexCache;\n  }\n\n  async listItems(args: ListItemsArgs = {}) {\n    const kind = args.kind || 'component';\n    const query = args.query ? normalizeValue(args.query) : null;\n    const packageName = args.package ? normalizeValue(args.package) : null;\n    const limit = clampLimit(args.limit, 30, 200);\n\n    const index = await this.getIndex();\n\n    return index\n      .filter((item) => item.kind === kind)\n      .filter((item) => (packageName ? normalizeValue(item.package) === packageName : true))\n      .filter((item) => {\n        if (!query) {\n          return true;\n        }\n\n        return (\n          normalizeValue(item.name).includes(query) ||\n          normalizeValue(item.description).includes(query) ||\n          normalizeValue(item.searchText).includes(query)\n        );\n      })\n      .slice(0, limit);\n  }\n\n  private scoreMatch(item: IndexItem, query: string) {\n    const normalizedQuery = normalizeValue(query);\n    const normalizedName = normalizeValue(item.name);\n\n    if (normalizedName === normalizedQuery) {\n      return 100;\n    }\n\n    if (normalizedName.startsWith(normalizedQuery)) {\n      return 80;\n    }\n\n    if (normalizedName.includes(normalizedQuery)) {\n      return 70;\n    }\n\n    if (normalizeValue(item.searchText).includes(normalizedQuery)) {\n      return 40;\n    }\n\n    const tokens = normalizedQuery.split(/\\s+/).filter(Boolean);\n    const matchedTokens = tokens.filter((token) => normalizeValue(item.searchText).includes(token));\n\n    if (tokens.length > 0 && matchedTokens.length > 0) {\n      return 10 + (matchedTokens.length / tokens.length) * 20;\n    }\n\n    return 0;\n  }\n\n  async searchDocs(args: SearchDocsArgs) {\n    const kind: ItemKind = args.kind || 'component';\n    const limit = clampLimit(args.limit, 20, 100);\n    const query = args.query.trim();\n\n    if (!query) {\n      return [];\n    }\n\n    const index = await this.getIndex();\n\n    return index\n      .filter((item) => item.kind === kind)\n      .map((item) => ({ item, score: this.scoreMatch(item, query) }))\n      .filter((entry) => entry.score > 0)\n      .sort((a, b) => b.score - a.score)\n      .slice(0, limit)\n      .map((entry) => ({\n        id: entry.item.id,\n        name: entry.item.name,\n        kind: entry.item.kind,\n        package: entry.item.package,\n        route: entry.item.route,\n        description: entry.item.description,\n        score: Number(entry.score.toFixed(2)),\n      }));\n  }\n\n  private async getItemDataById(id: string): Promise<ItemData> {\n    const cached = this.itemCache.get(id);\n    if (cached) {\n      return cached;\n    }\n\n    const data = await this.fetchJson<ItemData>(`components/${id}.json`);\n    this.itemCache.set(id, data);\n    return data;\n  }\n\n  async findItem(args: GetItemArgs) {\n    const kind = args.kind || 'component';\n    const requested = normalizeValue(args.name);\n    const index = await this.getIndex();\n\n    const byKind = index.filter((item) => item.kind === kind);\n\n    const exactId = byKind.find((item) => normalizeValue(item.id) === requested);\n    if (exactId) {\n      return exactId;\n    }\n\n    const exactName = byKind.find((item) => normalizeValue(item.name) === requested);\n    if (exactName) {\n      return exactName;\n    }\n\n    const prefixName = byKind.find((item) => normalizeValue(item.name).startsWith(requested));\n    if (prefixName) {\n      return prefixName;\n    }\n\n    return byKind.find((item) => normalizeValue(item.searchText).includes(requested)) || null;\n  }\n\n  async getItemDoc(args: GetItemArgs) {\n    const item = await this.findItem(args);\n    if (!item) {\n      return null;\n    }\n\n    const data = await this.getItemDataById(item.id);\n\n    return {\n      item: {\n        id: data.id,\n        name: data.name,\n        kind: data.kind,\n        package: data.package,\n        route: data.route,\n        description: data.description,\n        llmUrl: data.llmUrl,\n      },\n      markdown: data.markdown,\n    };\n  }\n\n  async getItemProps(args: GetItemArgs) {\n    const item = await this.findItem(args);\n    if (!item) {\n      return null;\n    }\n\n    const data = await this.getItemDataById(item.id);\n\n    return {\n      item: {\n        id: data.id,\n        name: data.name,\n        kind: data.kind,\n        package: data.package,\n        route: data.route,\n        description: data.description,\n      },\n      props: data.props,\n    };\n  }\n}\n"],"mappings":"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"}