{"version":3,"file":"index.cjs","sources":["../src/isVizId.ts","../src/isImageFileName.ts","../src/generateVizId.ts","../src/generateVizFileId.ts","../src/generateRunId.ts","../src/getFileId.ts","../src/getFileText.ts","../src/setFileText.ts","../src/vizFilesToFileCollection.ts","../src/fileCollectionToVizFiles.ts","../src/dateToTimestamp.ts","../src/timestampToDate.ts"],"sourcesContent":["import type { VizId } from \"@vizhub/viz-types\";\n\n// Checks if a string was generated by `generateId` from interactors.\nexport const isVizId = (str: string): boolean => {\n  // First check if the length is exactly 32 characters\n  if (str.length !== 32) {\n    return false;\n  }\n\n  // Regular expression for a 32-character hexadecimal string\n  let uuidV4NoDashRegex = /^[0-9a-f]{32}$/i;\n\n  // Check if the string matches the regular expression\n  if (!uuidV4NoDashRegex.test(str)) {\n    return false;\n  }\n\n  // Check if the 13th character is '4' (indicating UUID v4)\n  // and the 17th character is one of '8', '9', 'a', 'b' (indicating the variant)\n  return (\n    str[12] === \"4\"\n    // &&\n    // ['8', '9', 'a', 'b'].includes(str[16].toLowerCase())\n  );\n};\n","// Check if a file name has an image file extension\nexport const isImageFileName = (fileName: string): boolean => {\n  if (!fileName || typeof fileName !== \"string\" || fileName.trim() === \"\") {\n    return false;\n  }\n\n  // Check if it's an image file based on extension\n  // Also ensure there's at least one character before the dot\n  return /^.+\\.(png|jpg|jpeg|gif|bmp|svg|webp)$/i.test(fileName);\n};\n","import type { VizId } from \"@vizhub/viz-types\";\n\n// Resolve a Web‑Crypto‑compatible `crypto` object.\n// • Browsers & Node 19 +   → globalThis.crypto\n// • Anything else (rare)   → use node:crypto's webcrypto\nconst getCryptoObj = (): Crypto => {\n  if (typeof globalThis.crypto !== \"undefined\") {\n    return globalThis.crypto as Crypto;\n  }\n  // Use require instead of import to avoid top-level await\n  // This will only run in Node.js environments\n  return require(\"node:crypto\").webcrypto as Crypto;\n};\n\nconst cryptoObj = getCryptoObj();\n\n/**\n * Generates a dash‑free RFC 4122‑compliant UUID v4 (32 hex chars).\n * Works in all evergreen browsers and Node 19 + without extra deps.\n */\nexport const generateVizId = (): VizId => {\n  const bytes = new Uint8Array(16);\n  cryptoObj.getRandomValues(bytes);\n\n  // RFC 4122: set version (4) and variant (10xx)\n  bytes[6] = (bytes[6] & 0x0f) | 0x40;\n  bytes[8] = (bytes[8] & 0x3f) | 0x80;\n\n  return Array.from(bytes, (b) => b.toString(16).padStart(2, \"0\")).join(\n    \"\",\n  ) as VizId;\n};\n","import type { VizFileId } from \"@vizhub/viz-types\";\nimport { generateVizId } from \"./generateVizId\";\n\n// Generates a file id\nexport const generateVizFileId = (): VizFileId =>\n  generateVizId().substring(0, 8);\n","import { generateVizFileId } from \"./generateVizFileId\";\nexport const generateRunId = generateVizFileId;\n","import { VizContent, VizFileId } from \"@vizhub/viz-types\";\n\n// Gets the file id of a file with the given name.\n// Returns null if not found.\nexport const getFileId = (\n  content: VizContent,\n  fileName: string,\n): VizFileId | null => {\n  if (content && content.files) {\n    for (const fileId of Object.keys(content.files)) {\n      const file = content.files[fileId];\n      if (file.name === fileName) {\n        return fileId;\n      }\n    }\n  }\n  return null;\n};\n","import { VizContent } from \"@vizhub/viz-types\";\nimport { getFileId } from \"./getFileId\";\n\n// Gets the text content of a file with the given name.\n// Returns null if not found.\nexport const getFileText = (\n  content: VizContent,\n  fileName: string,\n): string | null => {\n  const fileId = getFileId(content, fileName);\n  if (fileId && content && content.files) {\n    return content.files[fileId].text;\n  }\n  return null;\n};\n","import { VizContent } from \"@vizhub/viz-types\";\nimport { getFileId } from \"./getFileId\";\nimport { generateVizFileId } from \"./generateVizFileId\";\n\n/**\n * Sets the text content of a file using an immutable update pattern.\n * If a file with the given fileName exists, its text is updated while preserving its fileId.\n * If no file with the given fileName exists, a new file is created with a generated fileId.\n *\n * @param content - The VizContent object to update (must not be null or undefined)\n * @param fileName - The name of the file (must be a non-empty string)\n * @param fileText - The new text content for the file (must be a non-empty string)\n * @returns A new VizContent object with the updated or newly created file\n * @throws Error if content is null or undefined\n * @throws Error if fileName is empty or not a string\n * @throws Error if fileText is empty or not a string\n */\nexport const setFileText = (\n  content: VizContent,\n  fileName: string,\n  fileText: string,\n): VizContent => {\n  // Validate content\n  if (content === null || content === undefined) {\n    throw new Error(\"Content cannot be null or undefined\");\n  }\n\n  // Validate fileName\n  if (typeof fileName !== \"string\" || fileName.length === 0) {\n    throw new Error(\"fileName must be a non-empty string\");\n  }\n\n  // Validate fileText\n  if (typeof fileText !== \"string\" || fileText.length === 0) {\n    throw new Error(\"fileText must be a non-empty string\");\n  }\n\n  // Initialize files object if it doesn't exist\n  const files = content.files || {};\n\n  // Try to find existing file with this name\n  const existingFileId = getFileId(content, fileName);\n\n  if (existingFileId) {\n    // Update existing file - shallow copy of files object\n    return {\n      ...content,\n      files: {\n        ...files,\n        [existingFileId]: {\n          ...files[existingFileId],\n          text: fileText,\n        },\n      },\n    };\n  } else {\n    // Create new file with generated ID\n    const newFileId = generateVizFileId();\n    return {\n      ...content,\n      files: {\n        ...files,\n        [newFileId]: {\n          name: fileName,\n          text: fileText,\n        },\n      },\n    };\n  }\n};\n","import type { VizFiles, FileCollection } from \"@vizhub/viz-types\";\n\n/**\n * Converts VizContent to FileCollection format.\n */\nexport const vizFilesToFileCollection = (files?: VizFiles): FileCollection => {\n  const fileCollection: FileCollection = {};\n\n  // Return empty object if files is undefined\n  if (!files) {\n    return fileCollection;\n  }\n\n  // Convert each VizFile to the FileCollection format\n  for (const file of Object.values(files)) {\n    fileCollection[file.name] = file.text;\n  }\n\n  return fileCollection;\n};\n","import { FileCollection, VizFiles } from \"@vizhub/viz-types\";\nimport { generateVizFileId } from \"./generateVizFileId\";\n\nexport const fileCollectionToVizFiles = (files: FileCollection): VizFiles => {\n  return Object.entries(files).reduce((acc, [name, text]) => {\n    acc[generateVizFileId()] = { name, text };\n    return acc;\n  }, {} as VizFiles);\n};\n","import type { VizTimestamp } from \"@vizhub/viz-types\";\n\nexport const dateToTimestamp = (date: Date): VizTimestamp =>\n  Math.floor(date.getTime() / 1000);\n","import type { VizTimestamp } from \"@vizhub/viz-types\";\n\nexport const timestampToDate = (timestamp: VizTimestamp): Date =>\n  new Date(timestamp * 1000);\n"],"names":["isVizId","str","isImageFileName","fileName","getCryptoObj","cryptoObj","generateVizId","bytes","b","generateVizFileId","generateRunId","getFileId","content","fileId","getFileText","setFileText","fileText","files","existingFileId","newFileId","vizFilesToFileCollection","fileCollection","file","fileCollectionToVizFiles","acc","name","text","dateToTimestamp","date","timestampToDate","timestamp"],"mappings":"gFAGO,MAAMA,EAAWC,GAElBA,EAAI,SAAW,IAQf,CAHoB,kBAGD,KAAKA,CAAG,EACtB,GAMPA,EAAI,EAAE,IAAM,ICnBHC,EAAmBC,GAC1B,CAACA,GAAY,OAAOA,GAAa,UAAYA,EAAS,KAAA,IAAW,GAC5D,GAKF,yCAAyC,KAAKA,CAAQ,ECHzDC,EAAe,IACf,OAAO,WAAW,OAAW,IACxB,WAAW,OAIb,QAAQ,aAAa,EAAE,UAG1BC,EAAYD,EAAA,EAMLE,EAAgB,IAAa,CACxC,MAAMC,EAAQ,IAAI,WAAW,EAAE,EAC/B,OAAAF,EAAU,gBAAgBE,CAAK,EAG/BA,EAAM,CAAC,EAAKA,EAAM,CAAC,EAAI,GAAQ,GAC/BA,EAAM,CAAC,EAAKA,EAAM,CAAC,EAAI,GAAQ,IAExB,MAAM,KAAKA,EAAQC,GAAMA,EAAE,SAAS,EAAE,EAAE,SAAS,EAAG,GAAG,CAAC,EAAE,KAC/D,EAAA,CAEJ,EC3BaC,EAAoB,IAC/BH,EAAA,EAAgB,UAAU,EAAG,CAAC,ECJnBI,EAAgBD,ECGhBE,EAAY,CACvBC,EACAT,IACqB,CACrB,GAAIS,GAAWA,EAAQ,OACrB,UAAWC,KAAU,OAAO,KAAKD,EAAQ,KAAK,EAE5C,GADaA,EAAQ,MAAMC,CAAM,EACxB,OAASV,EAChB,OAAOU,EAIb,OAAO,IACT,ECZaC,EAAc,CACzBF,EACAT,IACkB,CAClB,MAAMU,EAASF,EAAUC,EAAST,CAAQ,EAC1C,OAAIU,GAAUD,GAAWA,EAAQ,MACxBA,EAAQ,MAAMC,CAAM,EAAE,KAExB,IACT,ECGaE,EAAc,CACzBH,EACAT,EACAa,IACe,CAEf,GAAIJ,GAAY,KACd,MAAM,IAAI,MAAM,qCAAqC,EAIvD,GAAI,OAAOT,GAAa,UAAYA,EAAS,SAAW,EACtD,MAAM,IAAI,MAAM,qCAAqC,EAIvD,GAAI,OAAOa,GAAa,UAAYA,EAAS,SAAW,EACtD,MAAM,IAAI,MAAM,qCAAqC,EAIvD,MAAMC,EAAQL,EAAQ,OAAS,CAAA,EAGzBM,EAAiBP,EAAUC,EAAST,CAAQ,EAElD,GAAIe,EAEF,MAAO,CACL,GAAGN,EACH,MAAO,CACL,GAAGK,EACH,CAACC,CAAc,EAAG,CAChB,GAAGD,EAAMC,CAAc,EACvB,KAAMF,CAAA,CACR,CACF,EAEG,CAEL,MAAMG,EAAYV,EAAA,EAClB,MAAO,CACL,GAAGG,EACH,MAAO,CACL,GAAGK,EACH,CAACE,CAAS,EAAG,CACX,KAAMhB,EACN,KAAMa,CAAA,CACR,CACF,CAEJ,CACF,EChEaI,EAA4BH,GAAqC,CAC5E,MAAMI,EAAiC,CAAA,EAGvC,GAAI,CAACJ,EACH,OAAOI,EAIT,UAAWC,KAAQ,OAAO,OAAOL,CAAK,EACpCI,EAAeC,EAAK,IAAI,EAAIA,EAAK,KAGnC,OAAOD,CACT,EChBaE,EAA4BN,GAChC,OAAO,QAAQA,CAAK,EAAE,OAAO,CAACO,EAAK,CAACC,EAAMC,CAAI,KACnDF,EAAIf,EAAA,CAAmB,EAAI,CAAE,KAAAgB,EAAM,KAAAC,CAAA,EAC5BF,GACN,CAAA,CAAc,ECLNG,EAAmBC,GAC9B,KAAK,MAAMA,EAAK,QAAA,EAAY,GAAI,ECDrBC,EAAmBC,GAC9B,IAAI,KAAKA,EAAY,GAAI"}