{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "xlsx-sheetjs-flattener",
  "title": "XLSX SheetJS flattener",
  "description": "Pure SheetJS-to-compact-sheet flattening helpers for the XLSX viewer worker.",
  "dependencies": [
    "@e965/xlsx@0.20.3"
  ],
  "registryDependencies": [
    "@retab/xlsx-worker-protocol",
    "@retab/xlsx-workbook"
  ],
  "files": [
    {
      "path": "registry/new-york-v4/lib/xlsx-sheetjs-flattener.ts",
      "content": "import * as XLSX from \"@e965/xlsx\";\n\nimport { createCompactSheet, type CompactSheet } from \"@/lib/xlsx-workbook\";\nimport {\n  XLSX_PARSE_LIMITS,\n  XlsxWorkerError,\n  type XlsxParseLimits,\n} from \"@/lib/xlsx-worker-protocol\";\n\ntype SheetJsCell = {\n  t?: string;\n  v?: unknown;\n  w?: unknown;\n};\n\ntype SheetJsWorksheet = Record<string, SheetJsCell | string | undefined>;\n\ntype SheetJsWorkbook = {\n  SheetNames: string[];\n  Sheets: Record<string, SheetJsWorksheet | undefined>;\n};\n\nexport function flattenSheetJsWorkbook(\n  workbook: SheetJsWorkbook,\n  limits: XlsxParseLimits = XLSX_PARSE_LIMITS,\n): CompactSheet[] {\n  return workbook.SheetNames.map((name) =>\n    flattenSheetJsWorksheet(name, workbook.Sheets[name], limits),\n  );\n}\n\nexport function flattenSheetJsWorksheet(\n  name: string,\n  worksheet: SheetJsWorksheet | undefined,\n  limits: XlsxParseLimits = XLSX_PARSE_LIMITS,\n): CompactSheet {\n  const ref = worksheet?.[\"!ref\"];\n  if (typeof ref !== \"string\") {\n    return createEmptyCompactSheet(name);\n  }\n  const source = worksheet as SheetJsWorksheet;\n\n  const range = XLSX.utils.decode_range(ref);\n  if (!isValidDecodedRange(range)) return createEmptyCompactSheet(name);\n  const rowCount = range.e.r + 1;\n  const columnCount = range.e.c + 1;\n  const maxIndex = rowCount * columnCount - 1;\n  if (maxIndex > limits.maxRowMajorIndex) {\n    throw new XlsxWorkerError(\n      \"range_too_large\",\n      `Spreadsheet range is too large to preview (${rowCount} rows x ${columnCount} columns)`,\n    );\n  }\n\n  const entries: Array<{\n    cellIndex: number;\n    text: string;\n    numeric?: boolean;\n  }> = [];\n  let textChars = 0;\n\n  for (const key of Object.keys(source)) {\n    if (key.charCodeAt(0) === 33) continue;\n    const cell = source[key];\n    if (!isSheetJsCell(cell)) continue;\n    const { c: columnIndex, r: rowIndex } = XLSX.utils.decode_cell(key);\n    if (\n      rowIndex < range.s.r ||\n      columnIndex < range.s.c ||\n      rowIndex >= rowCount ||\n      columnIndex >= columnCount\n    ) {\n      continue;\n    }\n\n    const text =\n      cell.w != null ? String(cell.w) : cell.v != null ? String(cell.v) : \"\";\n    if (text === \"\") continue;\n    if (entries.length >= limits.maxNonEmptyCells) {\n      throw new XlsxWorkerError(\n        \"too_many_cells\",\n        `Spreadsheet has too many non-empty cells to preview (>${limits.maxNonEmptyCells.toLocaleString()})`,\n      );\n    }\n    textChars += text.length;\n    if (textChars > limits.maxTextChars) {\n      throw new XlsxWorkerError(\n        \"text_too_large\",\n        `Spreadsheet text is too large to preview (>${limits.maxTextChars.toLocaleString()} characters)`,\n      );\n    }\n\n    entries.push({\n      cellIndex: rowIndex * columnCount + columnIndex,\n      text,\n      numeric: cell.t === \"n\" || cell.t === \"d\",\n    });\n  }\n\n  return createCompactSheet({\n    name,\n    rowCount,\n    columnCount,\n    entries,\n  });\n}\n\nexport function compactWorkbookTransferBuffers(\n  sheets: CompactSheet[],\n): ArrayBuffer[] {\n  const transfer: ArrayBuffer[] = [];\n  for (const sheet of sheets) {\n    transfer.push(\n      sheet.cellIndexes.buffer as ArrayBuffer,\n      sheet.textOffsets.buffer as ArrayBuffer,\n      sheet.numericFlags.buffer as ArrayBuffer,\n    );\n  }\n  return transfer;\n}\n\nfunction isSheetJsCell(value: unknown): value is SheetJsCell {\n  return value != null && typeof value === \"object\";\n}\n\nfunction createEmptyCompactSheet(name: string) {\n  return createCompactSheet({\n    name,\n    rowCount: 0,\n    columnCount: 0,\n    entries: [],\n  });\n}\n\nfunction isValidDecodedRange(range: XLSX.Range) {\n  return (\n    range.s.r >= 0 &&\n    range.s.c >= 0 &&\n    range.e.r >= range.s.r &&\n    range.e.c >= range.s.c\n  );\n}\n",
      "type": "registry:lib",
      "target": "@lib/xlsx-sheetjs-flattener.ts"
    }
  ],
  "type": "registry:lib"
}