{
  "version": 3,
  "sources": ["../../src/object/to-json-compatible.ts"],
  "sourcesContent": ["import { escapeJsonPointer } from '@/json/escape-json-pointer'\nimport { Queue } from '@/queue/queue'\n\ntype RemoveCircularOptions = {\n  /** Prefix to add before the path in $ref values */\n  prefix?: string\n  /** Cache of already processed objects */\n  cache?: WeakMap<object, string>\n}\n\n/**\n * Traverses an object or array, returning a deep copy in which circular references are replaced\n * by JSON Reference objects of the form: `{ $ref: \"#/path/to/original\" }`.\n * This allows safe serialization of objects with cycles, following the JSON Reference convention (RFC 6901).\n * An optional `prefix` for the `$ref` path can be provided via options.\n *\n * @param obj - The input object or array to process\n * @param options - Optional configuration; you can set a prefix for $ref pointers\n * @returns A new object or array, with all circular references replaced by $ref pointers\n */\nexport const toJsonCompatible = <T>(obj: T, options: RemoveCircularOptions = {}): T => {\n  const { prefix = '', cache = new WeakMap<object, string>() } = options\n\n  const toRef = (path: string | undefined) => ({ $ref: `#${path ?? ''}` })\n\n  // Primitives and null are returned as-is\n  if (typeof obj !== 'object' || obj === null) {\n    return obj\n  }\n\n  const rootPath = prefix\n  cache.set(obj as object, rootPath)\n\n  const rootResult: unknown = Array.isArray(obj) ? new Array((obj as unknown[]).length) : {}\n\n  const queue = new Queue<{ node: object; result: unknown; path: string }>()\n  queue.enqueue({ node: obj as object, result: rootResult, path: rootPath })\n\n  while (!queue.isEmpty()) {\n    const frame = queue.dequeue()\n    if (!frame) {\n      continue\n    }\n\n    const { node, result, path } = frame\n\n    // Handle arrays (preserve sparse arrays like Array#map does)\n    if (Array.isArray(node)) {\n      const input = node as unknown[]\n      const out = result as unknown[]\n\n      for (let index = 0; index < input.length; index++) {\n        if (!(index in input)) {\n          continue\n        }\n\n        const item = input[index]\n        const itemPath = `${path}/${index}`\n\n        if (typeof item !== 'object' || item === null) {\n          out[index] = item\n          continue\n        }\n\n        const existingPath = cache.get(item as object)\n        if (existingPath !== undefined) {\n          out[index] = toRef(existingPath)\n          continue\n        }\n\n        cache.set(item as object, itemPath)\n\n        const childResult: unknown = Array.isArray(item) ? new Array((item as unknown[]).length) : {}\n        out[index] = childResult\n        queue.enqueue({ node: item as object, result: childResult, path: itemPath })\n      }\n\n      continue\n    }\n\n    // Handle objects - create a new object with processed values\n    const out = result as Record<string, unknown>\n    for (const [key, value] of Object.entries(node)) {\n      const valuePath = `${path}/${escapeJsonPointer(key)}`\n\n      if (typeof value !== 'object' || value === null) {\n        out[key] = value\n        continue\n      }\n\n      const existingPath = cache.get(value as object)\n      if (existingPath !== undefined) {\n        out[key] = toRef(existingPath)\n        continue\n      }\n\n      cache.set(value as object, valuePath)\n\n      const childResult: unknown = Array.isArray(value) ? new Array((value as unknown[]).length) : {}\n      out[key] = childResult\n      queue.enqueue({ node: value as object, result: childResult, path: valuePath })\n    }\n  }\n\n  return rootResult as T\n}\n"],
  "mappings": "AAAA,SAAS,yBAAyB;AAClC,SAAS,aAAa;AAmBf,MAAM,mBAAmB,CAAI,KAAQ,UAAiC,CAAC,MAAS;AACrF,QAAM,EAAE,SAAS,IAAI,QAAQ,oBAAI,QAAwB,EAAE,IAAI;AAE/D,QAAM,QAAQ,CAAC,UAA8B,EAAE,MAAM,IAAI,QAAQ,EAAE,GAAG;AAGtE,MAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;AAC3C,WAAO;AAAA,EACT;AAEA,QAAM,WAAW;AACjB,QAAM,IAAI,KAAe,QAAQ;AAEjC,QAAM,aAAsB,MAAM,QAAQ,GAAG,IAAI,IAAI,MAAO,IAAkB,MAAM,IAAI,CAAC;AAEzF,QAAM,QAAQ,IAAI,MAAuD;AACzE,QAAM,QAAQ,EAAE,MAAM,KAAe,QAAQ,YAAY,MAAM,SAAS,CAAC;AAEzE,SAAO,CAAC,MAAM,QAAQ,GAAG;AACvB,UAAM,QAAQ,MAAM,QAAQ;AAC5B,QAAI,CAAC,OAAO;AACV;AAAA,IACF;AAEA,UAAM,EAAE,MAAM,QAAQ,KAAK,IAAI;AAG/B,QAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,YAAM,QAAQ;AACd,YAAMA,OAAM;AAEZ,eAAS,QAAQ,GAAG,QAAQ,MAAM,QAAQ,SAAS;AACjD,YAAI,EAAE,SAAS,QAAQ;AACrB;AAAA,QACF;AAEA,cAAM,OAAO,MAAM,KAAK;AACxB,cAAM,WAAW,GAAG,IAAI,IAAI,KAAK;AAEjC,YAAI,OAAO,SAAS,YAAY,SAAS,MAAM;AAC7C,UAAAA,KAAI,KAAK,IAAI;AACb;AAAA,QACF;AAEA,cAAM,eAAe,MAAM,IAAI,IAAc;AAC7C,YAAI,iBAAiB,QAAW;AAC9B,UAAAA,KAAI,KAAK,IAAI,MAAM,YAAY;AAC/B;AAAA,QACF;AAEA,cAAM,IAAI,MAAgB,QAAQ;AAElC,cAAM,cAAuB,MAAM,QAAQ,IAAI,IAAI,IAAI,MAAO,KAAmB,MAAM,IAAI,CAAC;AAC5F,QAAAA,KAAI,KAAK,IAAI;AACb,cAAM,QAAQ,EAAE,MAAM,MAAgB,QAAQ,aAAa,MAAM,SAAS,CAAC;AAAA,MAC7E;AAEA;AAAA,IACF;AAGA,UAAM,MAAM;AACZ,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,YAAM,YAAY,GAAG,IAAI,IAAI,kBAAkB,GAAG,CAAC;AAEnD,UAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAC/C,YAAI,GAAG,IAAI;AACX;AAAA,MACF;AAEA,YAAM,eAAe,MAAM,IAAI,KAAe;AAC9C,UAAI,iBAAiB,QAAW;AAC9B,YAAI,GAAG,IAAI,MAAM,YAAY;AAC7B;AAAA,MACF;AAEA,YAAM,IAAI,OAAiB,SAAS;AAEpC,YAAM,cAAuB,MAAM,QAAQ,KAAK,IAAI,IAAI,MAAO,MAAoB,MAAM,IAAI,CAAC;AAC9F,UAAI,GAAG,IAAI;AACX,YAAM,QAAQ,EAAE,MAAM,OAAiB,QAAQ,aAAa,MAAM,UAAU,CAAC;AAAA,IAC/E;AAAA,EACF;AAEA,SAAO;AACT;",
  "names": ["out"]
}
