{"version":3,"file":"data_structure.mjs","names":[],"sources":["../../../src/batteries/tools/data_structure/index.ts"],"sourcesContent":["/**\n * Pre-constructed tools for querying, filtering, grouping, and reshaping structured values.\n *\n * @module @nhtio/adk/batteries/tools/data_structure\n *\n * @remarks\n * Pre-constructed bundled tools for the `data_structure` category. Import individually, the whole\n * category, or import every tool via `@nhtio/adk/batteries`.\n */\n\nimport { Tool } from '@nhtio/adk/common'\nimport { validator } from '@nhtio/validation'\nimport { isError, isObject } from '@nhtio/adk/guards'\nimport { bigSum, bigMean, formatBig, bigToNumber } from '@nhtio/adk/lib/helpers/bignum'\nimport type { BigNumber } from 'mathjs'\n\n/**\n * Render a {@link BigNumber} aggregate as a JSON-friendly value: a plain `number` when the result\n * is exactly representable as a float64 (|x| ≤ Number.MAX_SAFE_INTEGER, so existing consumers and\n * tests see a number with no precision loss), or a full-precision string otherwise — covering both\n * overflow (which `JSON.stringify` would turn into `null`) and the gap above 2^53 where float64\n * silently rounds (e.g. 3 × MAX_SAFE_INTEGER).\n */\nfunction aggregateValue(big: BigNumber): number | string {\n  const asNum = bigToNumber(big)\n  if (Number.isFinite(asNum) && Math.abs(asNum) <= Number.MAX_SAFE_INTEGER) return asNum\n  return formatBig(big, 16)\n}\n\nfunction getPath(obj: unknown, path: string): unknown {\n  const parts = path.split('.')\n  let current = obj\n  for (const part of parts) {\n    if (current === null || current === undefined || typeof current !== 'object') return undefined\n    current = (current as Record<string, unknown>)[part]\n  }\n  return current\n}\n\ntype FilterOperator =\n  | 'eq'\n  | 'ne'\n  | 'gt'\n  | 'gte'\n  | 'lt'\n  | 'lte'\n  | 'contains'\n  | 'starts_with'\n  | 'ends_with'\n  | 'exists'\n\nfunction matchesFilter(\n  item: unknown,\n  key: string,\n  operator: FilterOperator,\n  value: unknown\n): boolean {\n  const actual = getPath(item, key)\n  switch (operator) {\n    case 'eq':\n      return actual === value\n    case 'ne':\n      return actual !== value\n    case 'gt':\n      return typeof actual === 'number' && actual > (value as number)\n    case 'gte':\n      return typeof actual === 'number' && actual >= (value as number)\n    case 'lt':\n      return typeof actual === 'number' && actual < (value as number)\n    case 'lte':\n      return typeof actual === 'number' && actual <= (value as number)\n    case 'contains':\n      return typeof actual === 'string' && actual.includes(String(value))\n    case 'starts_with':\n      return typeof actual === 'string' && actual.startsWith(String(value))\n    case 'ends_with':\n      return typeof actual === 'string' && actual.endsWith(String(value))\n    case 'exists':\n      return actual !== undefined && actual !== null\n    default:\n      return false\n  }\n}\n\nfunction medianOf(nums: number[]): number {\n  const sorted = [...nums].sort((a, b) => a - b)\n  const mid = Math.floor(sorted.length / 2)\n  return sorted.length % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid]\n}\n\nfunction applyTemplate(template: string, item: unknown): string {\n  if (typeof item !== 'object' || item === null) return String(item)\n  return template.replace(/\\{\\{([^}]+)\\}\\}/g, (_, key) => {\n    const val = getPath(item, key.trim())\n    return val === undefined || val === null ? '' : String(val)\n  })\n}\n\ntype Operation =\n  | { op: 'filter'; key: string; operator: FilterOperator; value?: unknown }\n  | { op: 'sort'; key: string; direction?: 'asc' | 'desc' }\n  | { op: 'select_keys'; keys: string[] }\n  | { op: 'pluck'; key: string }\n  | { op: 'slice'; start: number; end?: number }\n  | { op: 'unique' }\n  | { op: 'unique_by'; key: string }\n  | { op: 'group_by'; key: string }\n  | { op: 'flatten'; depth?: number }\n  | { op: 'reverse' }\n  | { op: 'count' }\n  | { op: 'sum'; key?: string }\n  | { op: 'avg'; key?: string }\n  | { op: 'median'; key?: string }\n  | { op: 'min'; key?: string }\n  | { op: 'max'; key?: string }\n  | { op: 'first'; n?: number }\n  | { op: 'last'; n?: number }\n  | { op: 'chunk'; size: number }\n  | { op: 'frequency_count'; key?: string }\n  | { op: 'top_n'; n: number; key: string; direction?: 'asc' | 'desc' }\n  | { op: 'map_template'; template: string }\n\nfunction applyOperation(data: unknown, op: Operation): unknown {\n  // Guard malformed pipeline entries (null, non-object, or missing `op`) so they produce a clear\n  // error string rather than a TypeError from dereferencing `op.op`.\n  if (op === null || typeof op !== 'object' || typeof (op as { op?: unknown }).op !== 'string') {\n    throw new Error('Each operation must be an object with a string \"op\" field.')\n  }\n\n  if (op.op === 'count') {\n    if (Array.isArray(data)) return data.length\n    if (isObject(data)) return Object.keys(data).length\n    return 0\n  }\n\n  if (!Array.isArray(data)) {\n    throw new Error(`Operation \"${op.op}\" requires an array input.`)\n  }\n\n  const arr = data as unknown[]\n\n  switch (op.op) {\n    case 'filter':\n      return arr.filter((item) => matchesFilter(item, op.key, op.operator, op.value))\n\n    case 'sort': {\n      const dir = op.direction === 'desc' ? -1 : 1\n      return [...arr].sort((a, b) => {\n        const av = getPath(a, op.key)\n        const bv = getPath(b, op.key)\n        if (av === bv) return 0\n        if (av === undefined || av === null) return 1\n        if (bv === undefined || bv === null) return -1\n        if (typeof av === 'number' && typeof bv === 'number') return (av - bv) * dir\n        return String(av).localeCompare(String(bv)) * dir\n      })\n    }\n\n    case 'select_keys':\n      return arr.map((item) => {\n        if (typeof item !== 'object' || item === null) return item\n        const result: Record<string, unknown> = {}\n        for (const key of op.keys) result[key] = (item as Record<string, unknown>)[key]\n        return result\n      })\n\n    case 'pluck':\n      return arr.map((item) => getPath(item, op.key))\n\n    case 'slice':\n      return arr.slice(op.start, op.end)\n\n    case 'unique': {\n      const seen = new Set<string>()\n      return arr.filter((item) => {\n        const key = typeof item === 'object' ? JSON.stringify(item) : String(item)\n        if (seen.has(key)) return false\n        seen.add(key)\n        return true\n      })\n    }\n\n    case 'unique_by': {\n      const seen = new Set<string>()\n      return arr.filter((item) => {\n        const raw = getPath(item, op.key)\n        // Serialise the key value so deep-equal objects/arrays dedupe by VALUE, not reference —\n        // JSON.parse produces a distinct reference per row, so a raw Set never matched them. This\n        // must catch BOTH plain objects and arrays, so a raw `typeof === 'object'` is intended here\n        // rather than the plain-object-only `isObject` guard.\n        // eslint-disable-next-line adk/prefer-is-object\n        const isObjectOrArray = typeof raw === 'object' && raw !== null\n        const key = isObjectOrArray ? JSON.stringify(raw) : `${typeof raw}:${String(raw)}`\n        if (seen.has(key)) return false\n        seen.add(key)\n        return true\n      })\n    }\n\n    case 'group_by': {\n      const groups: Record<string, unknown[]> = {}\n      for (const item of arr) {\n        const key = String(getPath(item, op.key) ?? '__undefined__')\n        if (!groups[key]) groups[key] = []\n        groups[key].push(item)\n      }\n      return groups\n    }\n\n    case 'flatten':\n      return arr.flat(op.depth ?? 1)\n\n    case 'reverse':\n      return [...arr].reverse()\n\n    case 'sum': {\n      // The total is accumulated in BigNumber so a sum exceeding float64 stays exact (returned as\n      // a precise string) instead of silently becoming Infinity → JSON null.\n      const values = op.key ? arr.map((i) => getPath(i, op.key!)) : arr\n      const nums = values.filter((v): v is number => typeof v === 'number' && Number.isFinite(v))\n      // A non-empty input with no numeric values is almost always a mistake (e.g. an array of\n      // objects summed without a `key`). Returning 0 would be silently wrong, so error instead.\n      if (nums.length === 0 && arr.length > 0) {\n        throw new Error(\n          op.key\n            ? `No numeric values found at key \"${op.key}\".`\n            : 'No numeric values to sum. For an array of objects, pass a \"key\".'\n        )\n      }\n      return aggregateValue(bigSum(nums))\n    }\n\n    case 'avg': {\n      const values = op.key ? arr.map((i) => getPath(i, op.key!)) : arr\n      const nums = values.filter((v): v is number => typeof v === 'number' && Number.isFinite(v))\n      // null (not 0) signals \"no numeric data\" — unlike sum, an average has no neutral element,\n      // so null is an honest \"no result\" rather than a misleading number.\n      if (nums.length === 0) return null\n      return aggregateValue(bigMean(nums))\n    }\n\n    case 'median': {\n      const values = op.key ? arr.map((i) => getPath(i, op.key!)) : arr\n      const nums = values.filter((v): v is number => typeof v === 'number' && Number.isFinite(v))\n      if (nums.length === 0) return null\n      return medianOf(nums)\n    }\n\n    case 'min': {\n      const values = op.key ? arr.map((i) => getPath(i, op.key!)) : arr\n      const nums = values.filter((v): v is number => typeof v === 'number')\n      if (nums.length === 0) return null\n      return Math.min(...nums)\n    }\n\n    case 'max': {\n      const values = op.key ? arr.map((i) => getPath(i, op.key!)) : arr\n      const nums = values.filter((v): v is number => typeof v === 'number')\n      if (nums.length === 0) return null\n      return Math.max(...nums)\n    }\n\n    case 'first':\n      return op.n !== undefined ? arr.slice(0, op.n) : arr[0]\n\n    case 'last':\n      return op.n !== undefined ? arr.slice(-op.n) : arr[arr.length - 1]\n\n    case 'chunk': {\n      const size = Math.max(1, Math.floor(op.size))\n      const chunks: unknown[][] = []\n      for (let i = 0; i < arr.length; i += size) chunks.push(arr.slice(i, i + size))\n      return chunks\n    }\n\n    case 'frequency_count': {\n      const freq: Record<string, number> = {}\n      for (const item of arr) {\n        const key = op.key ? String(getPath(item, op.key) ?? '__undefined__') : String(item)\n        freq[key] = (freq[key] ?? 0) + 1\n      }\n      return freq\n    }\n\n    case 'top_n': {\n      // desc (default) ranks largest-first; asc ranks smallest-first. The base comparator\n      // `(bv - av)` / `localeCompare(bv, av)` is descending, so asc flips it.\n      const dir = op.direction === 'asc' ? -1 : 1\n      return [...arr]\n        .sort((a, b) => {\n          const av = getPath(a, op.key)\n          const bv = getPath(b, op.key)\n          if (typeof av === 'number' && typeof bv === 'number') return (bv - av) * dir\n          return String(bv).localeCompare(String(av)) * dir\n        })\n        .slice(0, op.n)\n    }\n\n    case 'map_template':\n      return arr.map((item) => applyTemplate(op.template, item))\n\n    default:\n      throw new Error(`Unknown operation: ${(op as { op: string }).op}`)\n  }\n}\n\n/**\n * Apply a pipeline of operations to a JSON array or object.\n *\n * @remarks\n * Operations are applied in order; each step transforms the output of the previous. Supported\n * operations: `filter`, `sort`, `select_keys`, `pluck`, `slice`, `unique`, `unique_by`,\n * `group_by`, `flatten`, `reverse`, `count`, `sum`, `avg`, `median`, `min`, `max`, `first`,\n * `last`, `chunk`, `frequency_count`, `top_n`, `map_template`. Dot-notation paths are supported\n * for nested key access in every operation that takes a `key` field.\n */\nexport const jsonTransformTool = new Tool({\n  name: 'json_transform',\n  description:\n    'Apply a pipeline of operations to a JSON array or object: filter, sort, group, aggregate (sum/avg/median/min/max), pluck fields, deduplicate, flatten, chunk, frequency count, top-N, and more.',\n  inputSchema: validator.object({\n    data: validator.string().required().description('JSON data as a string (array or object)'),\n    operations: validator\n      .array()\n      .items(validator.object().unknown(true))\n      .required()\n      .description(\n        'Pipeline of operations to apply in order. Each step transforms the output of the previous.'\n      ),\n  }),\n  handler: async (args) => {\n    const { data: dataStr, operations } = args as {\n      data: string\n      operations: Operation[]\n    }\n\n    let data: unknown\n    try {\n      data = JSON.parse(dataStr)\n    } catch {\n      return 'Error: Invalid JSON input.'\n    }\n\n    let current: unknown = data\n\n    for (const [i, operation] of operations.entries()) {\n      try {\n        current = applyOperation(current, operation)\n      } catch (err) {\n        const opName =\n          operation && typeof operation === 'object' && 'op' in operation\n            ? String((operation as { op: unknown }).op)\n            : String(operation)\n        return `Error in operation ${i + 1} (\"${opName}\"): ${isError(err) ? err.message : String(err)}`\n      }\n    }\n\n    if (typeof current === 'string') return current\n    return JSON.stringify(current, null, 2)\n  },\n})\n\n/**\n * Perform set operations on two JSON arrays.\n *\n * @remarks\n * Supported operations: `intersection`, `union`, `difference`, `symmetric_difference`,\n * `is_member`, `is_subset`, `is_superset`. For arrays of objects, an optional `compare_key`\n * narrows equality to a single property rather than deep structural comparison.\n */\nexport const setOperationsTool = new Tool({\n  name: 'set_operations',\n  description:\n    'Perform set operations on two JSON arrays: intersection (common elements), union (all elements), difference (in A but not B), symmetric difference, or membership check.',\n  inputSchema: validator.object({\n    data_a: validator.string().required().description('First JSON array'),\n    data_b: validator\n      .string()\n      .optional()\n      .allow('')\n      .description(\n        'Second JSON array. Omit or send an empty string to skip the second-array comparison.'\n      ),\n    operation: validator\n      .string()\n      .valid(\n        'intersection',\n        'union',\n        'difference',\n        'symmetric_difference',\n        'is_member',\n        'is_subset',\n        'is_superset'\n      )\n      .required()\n      .description('Set operation to perform'),\n    item: validator.any().optional().description('For is_member: the value to look up in data_a.'),\n    compare_key: validator\n      .string()\n      .optional()\n      .allow('')\n      .description(\n        'For arrays of objects: use this key for equality comparison instead of deep equality. Omit or send an empty string to use deep equality.'\n      ),\n  }),\n  handler: async (args) => {\n    const {\n      data_a: dataA,\n      data_b: dataB,\n      operation,\n      item,\n      compare_key: compareKey,\n    } = args as {\n      data_a: string\n      data_b?: string\n      operation: string\n      item?: unknown\n      compare_key?: string\n    }\n\n    let a: unknown[]\n    let b: unknown[] = []\n\n    try {\n      a = JSON.parse(dataA)\n    } catch {\n      return 'Error: data_a is not valid JSON.'\n    }\n    if (!Array.isArray(a)) return 'Error: data_a must be a JSON array.'\n\n    if (dataB !== undefined && dataB !== '') {\n      try {\n        b = JSON.parse(dataB)\n      } catch {\n        return 'Error: data_b is not valid JSON.'\n      }\n      if (!Array.isArray(b)) return 'Error: data_b must be a JSON array.'\n    }\n\n    const toKey = (val: unknown): string =>\n      compareKey && isObject(val)\n        ? String((val as Record<string, unknown>)[compareKey])\n        : JSON.stringify(val)\n\n    if (operation === 'is_member') {\n      const needle = JSON.stringify(item)\n      const found = a.some((entry) => JSON.stringify(entry) === needle)\n      return found ? `Found: item is in the array.` : `Not found: item is not in the array.`\n    }\n\n    const setA = new Set(a.map(toKey))\n    const setB = new Set(b.map(toKey))\n    const indexA = new Map(a.map((entry) => [toKey(entry), entry]))\n\n    switch (operation) {\n      case 'intersection': {\n        const result = [...setA].filter((k) => setB.has(k)).map((k) => indexA.get(k))\n        return JSON.stringify(result, null, 2)\n      }\n      case 'union': {\n        const result = [...a, ...b.filter((entry) => !setA.has(toKey(entry)))]\n        return JSON.stringify(result, null, 2)\n      }\n      case 'difference': {\n        const result = a.filter((entry) => !setB.has(toKey(entry)))\n        return JSON.stringify(result, null, 2)\n      }\n      case 'symmetric_difference': {\n        const result = [\n          ...a.filter((entry) => !setB.has(toKey(entry))),\n          ...b.filter((entry) => !setA.has(toKey(entry))),\n        ]\n        return JSON.stringify(result, null, 2)\n      }\n      case 'is_subset':\n        return [...setA].every((k) => setB.has(k))\n          ? `Yes: A is a subset of B (all ${a.length} elements of A are in B).`\n          : `No: A is not a subset of B.`\n      case 'is_superset':\n        return [...setB].every((k) => setA.has(k))\n          ? `Yes: A is a superset of B (A contains all ${b.length} elements of B).`\n          : `No: A is not a superset of B.`\n      default:\n        return `Error: Unknown operation \"${operation}\".`\n    }\n  },\n})\n"],"mappings":"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"}