@paperjsx/json-to-xlsx-pro 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +7 -0
- package/README.md +61 -0
- package/dist/assembly/xlsx-assembler.d.ts +53 -0
- package/dist/assembly/xlsx-assembler.d.ts.map +1 -0
- package/dist/benchmarks/phase2.d.ts +72 -0
- package/dist/benchmarks/phase2.d.ts.map +1 -0
- package/dist/benchmarks/phase2.js +14 -0
- package/dist/benchmarks/phase2.js.map +7 -0
- package/dist/benchmarks/report.d.ts +21 -0
- package/dist/benchmarks/report.d.ts.map +1 -0
- package/dist/benchmarks/report.js +13 -0
- package/dist/benchmarks/report.js.map +7 -0
- package/dist/benchmarks/rigorous.d.ts +85 -0
- package/dist/benchmarks/rigorous.d.ts.map +1 -0
- package/dist/benchmarks/rigorous.js +534 -0
- package/dist/benchmarks/rigorous.js.map +7 -0
- package/dist/chaos-lab/index.d.ts +69 -0
- package/dist/chaos-lab/index.d.ts.map +1 -0
- package/dist/chaos-lab/index.js +1696 -0
- package/dist/chaos-lab/index.js.map +7 -0
- package/dist/chunk-2IVXCH6I.js +1002 -0
- package/dist/chunk-2IVXCH6I.js.map +7 -0
- package/dist/chunk-IYMS2CLX.js +478 -0
- package/dist/chunk-IYMS2CLX.js.map +7 -0
- package/dist/chunk-PQSLPEN5.js +290 -0
- package/dist/chunk-PQSLPEN5.js.map +7 -0
- package/dist/chunk-QDWDSM74.js +142 -0
- package/dist/chunk-QDWDSM74.js.map +7 -0
- package/dist/chunk-S5RMAWLC.js +25347 -0
- package/dist/chunk-S5RMAWLC.js.map +7 -0
- package/dist/chunk-Z2JSZFNG.js +308 -0
- package/dist/chunk-Z2JSZFNG.js.map +7 -0
- package/dist/diagnostics/corruption.d.ts +9 -0
- package/dist/diagnostics/corruption.d.ts.map +1 -0
- package/dist/diagnostics/workloads.d.ts +6 -0
- package/dist/diagnostics/workloads.d.ts.map +1 -0
- package/dist/diff/document-diff.d.ts +5 -0
- package/dist/diff/document-diff.d.ts.map +1 -0
- package/dist/document-diff/src/index.d.ts +50 -0
- package/dist/document-diff/src/index.d.ts.map +1 -0
- package/dist/errors.d.ts +35 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/fixtures/phase1.d.ts +14 -0
- package/dist/fixtures/phase1.d.ts.map +1 -0
- package/dist/fixtures/phase2.d.ts +9 -0
- package/dist/fixtures/phase2.d.ts.map +1 -0
- package/dist/fixtures/phase3.d.ts +9 -0
- package/dist/fixtures/phase3.d.ts.map +1 -0
- package/dist/fixtures/phase4.d.ts +10 -0
- package/dist/fixtures/phase4.d.ts.map +1 -0
- package/dist/fixtures/phase5.d.ts +9 -0
- package/dist/fixtures/phase5.d.ts.map +1 -0
- package/dist/formulas/builder.d.ts +91 -0
- package/dist/formulas/builder.d.ts.map +1 -0
- package/dist/formulas/evaluator.d.ts +25 -0
- package/dist/formulas/evaluator.d.ts.map +1 -0
- package/dist/formulas/shift.d.ts +14 -0
- package/dist/formulas/shift.d.ts.map +1 -0
- package/dist/index-pro.d.ts +12 -0
- package/dist/index-pro.d.ts.map +1 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2167 -0
- package/dist/index.js.map +7 -0
- package/dist/layout/column-width.d.ts +32 -0
- package/dist/layout/column-width.d.ts.map +1 -0
- package/dist/layout/row-height.d.ts +3 -0
- package/dist/layout/row-height.d.ts.map +1 -0
- package/dist/preflight.d.ts +31 -0
- package/dist/preflight.d.ts.map +1 -0
- package/dist/public-quality-types.d.ts +44 -0
- package/dist/public-quality-types.d.ts.map +1 -0
- package/dist/quality/accessibility-contract.d.ts +38 -0
- package/dist/quality/accessibility-contract.d.ts.map +1 -0
- package/dist/quality/accessibility.d.ts +33 -0
- package/dist/quality/accessibility.d.ts.map +1 -0
- package/dist/quality/shared-quality.d.ts +4 -0
- package/dist/quality/shared-quality.d.ts.map +1 -0
- package/dist/quality/structural-validation.d.ts +11 -0
- package/dist/quality/structural-validation.d.ts.map +1 -0
- package/dist/quality/workbook-quality.d.ts +63 -0
- package/dist/quality/workbook-quality.d.ts.map +1 -0
- package/dist/render-metrics.d.ts +67 -0
- package/dist/render-metrics.d.ts.map +1 -0
- package/dist/render-plan.d.ts +40 -0
- package/dist/render-plan.d.ts.map +1 -0
- package/dist/serializers/chart-serializer.d.ts +3 -0
- package/dist/serializers/chart-serializer.d.ts.map +1 -0
- package/dist/serializers/comment-serializer.d.ts +12 -0
- package/dist/serializers/comment-serializer.d.ts.map +1 -0
- package/dist/serializers/doc-props-serializer.d.ts +5 -0
- package/dist/serializers/doc-props-serializer.d.ts.map +1 -0
- package/dist/serializers/drawing-serializer.d.ts +24 -0
- package/dist/serializers/drawing-serializer.d.ts.map +1 -0
- package/dist/serializers/package-serializer.d.ts +13 -0
- package/dist/serializers/package-serializer.d.ts.map +1 -0
- package/dist/serializers/pivot-serializer.d.ts +37 -0
- package/dist/serializers/pivot-serializer.d.ts.map +1 -0
- package/dist/serializers/shared-strings.d.ts +11 -0
- package/dist/serializers/shared-strings.d.ts.map +1 -0
- package/dist/serializers/sheet-serializer.d.ts +58 -0
- package/dist/serializers/sheet-serializer.d.ts.map +1 -0
- package/dist/serializers/sheet-xml-builder.d.ts +33 -0
- package/dist/serializers/sheet-xml-builder.d.ts.map +1 -0
- package/dist/serializers/style-registry.d.ts +2 -0
- package/dist/serializers/style-registry.d.ts.map +1 -0
- package/dist/serializers/table-serializer.d.ts +20 -0
- package/dist/serializers/table-serializer.d.ts.map +1 -0
- package/dist/serializers/theme-serializer.d.ts +3 -0
- package/dist/serializers/theme-serializer.d.ts.map +1 -0
- package/dist/serializers/workbook-serializer.d.ts +16 -0
- package/dist/serializers/workbook-serializer.d.ts.map +1 -0
- package/dist/serializers/worksheet-rels-serializer.d.ts +7 -0
- package/dist/serializers/worksheet-rels-serializer.d.ts.map +1 -0
- package/dist/source-js-extension-loader.mjs +44 -0
- package/dist/spreadsheet-engine.d.ts +50 -0
- package/dist/spreadsheet-engine.d.ts.map +1 -0
- package/dist/styles/border-serializer.d.ts +6 -0
- package/dist/styles/border-serializer.d.ts.map +1 -0
- package/dist/styles/color.d.ts +5 -0
- package/dist/styles/color.d.ts.map +1 -0
- package/dist/styles/component-registry.d.ts +13 -0
- package/dist/styles/component-registry.d.ts.map +1 -0
- package/dist/styles/conditional-formatting.d.ts +8 -0
- package/dist/styles/conditional-formatting.d.ts.map +1 -0
- package/dist/styles/fill-serializer.d.ts +9 -0
- package/dist/styles/fill-serializer.d.ts.map +1 -0
- package/dist/styles/font-serializer.d.ts +11 -0
- package/dist/styles/font-serializer.d.ts.map +1 -0
- package/dist/styles/numfmt-registry.d.ts +7 -0
- package/dist/styles/numfmt-registry.d.ts.map +1 -0
- package/dist/styles/presets.d.ts +190 -0
- package/dist/styles/presets.d.ts.map +1 -0
- package/dist/styles/style-registry.d.ts +24 -0
- package/dist/styles/style-registry.d.ts.map +1 -0
- package/dist/styles/style-utils.d.ts +11 -0
- package/dist/styles/style-utils.d.ts.map +1 -0
- package/dist/template-assembler.d.ts +26 -0
- package/dist/template-assembler.d.ts.map +1 -0
- package/dist/template-parser.d.ts +96 -0
- package/dist/template-parser.d.ts.map +1 -0
- package/dist/types/spreadsheet-ast.d.ts +470 -0
- package/dist/types/spreadsheet-ast.d.ts.map +1 -0
- package/dist/utils/cell-ref.d.ts +21 -0
- package/dist/utils/cell-ref.d.ts.map +1 -0
- package/dist/utils/date.d.ts +32 -0
- package/dist/utils/date.d.ts.map +1 -0
- package/dist/utils/hyperlinks.d.ts +16 -0
- package/dist/utils/hyperlinks.d.ts.map +1 -0
- package/dist/utils/xml.d.ts +7 -0
- package/dist/utils/xml.d.ts.map +1 -0
- package/dist/validation/spreadsheet-schema.d.ts +1513 -0
- package/dist/validation/spreadsheet-schema.d.ts.map +1 -0
- package/dist/workers/sheet-serialization-worker-pool.d.ts +32 -0
- package/dist/workers/sheet-serialization-worker-pool.d.ts.map +1 -0
- package/dist/workers/sheet-serializer-worker.d.ts +2 -0
- package/dist/workers/sheet-serializer-worker.d.ts.map +1 -0
- package/dist/workers/sheet-serializer-worker.js +2565 -0
- package/dist/workers/sheet-serializer-worker.js.map +7 -0
- package/dist/worksheet/structure.d.ts +33 -0
- package/dist/worksheet/structure.d.ts.map +1 -0
- package/dist-pro/benchmarks/phase2.js +1 -0
- package/dist-pro/benchmarks/report.js +1 -0
- package/dist-pro/benchmarks/rigorous.js +2 -0
- package/dist-pro/chaos-lab/index.js +2 -0
- package/dist-pro/chunk-FFIHITWB.js +1 -0
- package/dist-pro/chunk-INDNGGXB.js +2 -0
- package/dist-pro/chunk-K2MQYNU6.js +1 -0
- package/dist-pro/chunk-MEZHQFH3.js +2 -0
- package/dist-pro/chunk-RB42Q36L.js +1 -0
- package/dist-pro/chunk-WYTH4W4N.js +48 -0
- package/dist-pro/index.js +3 -0
- package/dist-pro/source-js-extension-loader.mjs +44 -0
- package/dist-pro/workers/sheet-serializer-worker.js +3 -0
- package/package.json +62 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/diagnostics/workloads.ts", "../src/diagnostics/corruption.ts"],
|
|
4
|
+
"sourcesContent": ["import type {\n SpreadsheetCellStyle,\n SpreadsheetDocument,\n} from \"../types/spreadsheet-ast.js\";\n\nconst BORDER_STYLES = [\n \"thin\",\n \"medium\",\n \"thick\",\n \"double\",\n \"dotted\",\n \"dashed\",\n \"dashDot\",\n \"dashDotDot\",\n \"hair\",\n \"mediumDashed\",\n \"mediumDashDot\",\n \"mediumDashDotDot\",\n \"slantDashDot\",\n] as const;\n\nconst H_ALIGNMENTS = [\n \"left\",\n \"center\",\n \"right\",\n \"justify\",\n \"distributed\",\n \"general\",\n] as const;\n\nconst V_ALIGNMENTS = [\"top\", \"center\", \"bottom\"] as const;\nconst FORMAT_ALIASES = [\n \"currency\",\n \"currency:KRW\",\n \"currency:EUR\",\n \"percentage\",\n \"percentage:2\",\n \"date\",\n \"datetime\",\n \"accounting\",\n \"number:0\",\n \"number:2\",\n] as const;\n\nfunction createStyle(index: number): SpreadsheetCellStyle {\n const primary = (index * 2_654_435_761) % 0xFFFFFF;\n const secondary = (index * 40_503) % 0xFFFFFF;\n const tertiary = (index * 811) % 0xFFFFFF;\n return {\n font: {\n family: index % 3 === 0 ? \"Calibri\" : (index % 3 === 1 ? \"Arial\" : \"Courier New\"),\n size: 10 + (index % 4),\n bold: index % 2 === 0,\n italic: index % 5 === 0,\n underline: index % 7 === 0 ? \"single\" : undefined,\n color: `#${primary.toString(16).padStart(6, \"0\")}`,\n },\n fill: {\n color: `#${secondary.toString(16).padStart(6, \"0\")}`,\n },\n border: {\n bottom: {\n style: BORDER_STYLES[index % BORDER_STYLES.length],\n color: `#${tertiary.toString(16).padStart(6, \"0\")}`,\n },\n },\n alignment: {\n horizontal: H_ALIGNMENTS[index % H_ALIGNMENTS.length],\n vertical: V_ALIGNMENTS[index % V_ALIGNMENTS.length],\n wrapText: index % 4 === 0,\n },\n numberFormat: FORMAT_ALIASES[index % FORMAT_ALIASES.length],\n };\n}\n\nfunction createStylePalette(size: number): SpreadsheetCellStyle[] {\n return Array.from({ length: size }, (_unused, index) => createStyle(index));\n}\n\nexport function createStyledWorkbook(\n rowCount: number,\n colCount: number,\n paletteSize: number,\n sheetName: string,\n): SpreadsheetDocument {\n const palette = createStylePalette(paletteSize);\n const rows = Array.from({ length: rowCount }, (_rowUnused, rowIndex) => ({\n cells: Array.from({ length: colCount }, (_colUnused, colIndex) => {\n const ordinal = rowIndex * colCount + colIndex;\n const style = palette[ordinal % palette.length];\n\n if (colIndex % 5 === 0) {\n return { value: `Row ${rowIndex + 1}`, style };\n }\n if (colIndex % 5 === 1) {\n return { value: ordinal, style };\n }\n if (colIndex % 5 === 2) {\n return { value: (rowIndex + 1) / (colIndex + 1), style };\n }\n if (colIndex % 5 === 3) {\n return { value: rowIndex % 2 === 0, style };\n }\n return { value: new Date(Date.UTC(2026, 0, (rowIndex % 28) + 1)), style };\n }),\n }));\n\n return {\n meta: {\n title: `${sheetName} ${rowCount}x${colCount}`,\n creator: \"PaperJSX\",\n },\n sheets: [\n {\n name: sheetName,\n rows,\n },\n ],\n };\n}\n\nexport function createRepairCorpusDocument(): SpreadsheetDocument {\n return {\n namedRanges: [\n { name: \"LedgerWindow\", ref: \"Ledger!$A$2:$D$5\" },\n ],\n sheets: [\n {\n name: \"Ledger\",\n dataValidations: [\n {\n ref: \"C3:C20\",\n type: \"list\",\n formula1: \"\\\"Open,Closed,Pending\\\"\",\n allowBlank: true,\n },\n ],\n rows: [\n {\n cells: [\n {\n value: \"Ledger Overview\",\n colSpan: 4,\n style: {\n fill: { color: \"#D9E2F3\" },\n alignment: { horizontal: \"center\", vertical: \"center\" },\n border: {\n top: { style: \"thin\", color: \"#5B9BD5\" },\n bottom: { style: \"thin\", color: \"#5B9BD5\" },\n left: { style: \"thin\", color: \"#5B9BD5\" },\n right: { style: \"thin\", color: \"#5B9BD5\" },\n },\n },\n },\n ],\n },\n {\n cells: [\n { value: \"Account\", style: \"header\" },\n { value: \"Amount\", style: \"header\" },\n { value: \"Status\", style: \"header\" },\n { value: \"Docs\", style: \"header\" },\n ],\n },\n {\n cells: [\n { value: \"Northwind\" },\n { value: 120_000, style: \"currency\" },\n { value: \"Open\" },\n {\n value: \"Policy\",\n hyperlink: {\n target: \"https://example.com/policy\",\n tooltip: \"Open the policy document\",\n },\n },\n ],\n },\n {\n cells: [\n { value: \"Contoso\" },\n { value: 85_500, style: \"currency\" },\n { value: \"Closed\" },\n {\n value: \"Guide\",\n hyperlink: {\n location: \"Lookups!A1\",\n display: \"Jump to lookup sheet\",\n },\n },\n ],\n },\n {\n cells: [\n { value: \"Fabrikam\" },\n { value: 61_250, style: \"currency\" },\n { value: \"Pending\" },\n { value: \"Escalated\" },\n ],\n },\n ],\n tables: [\n {\n name: \"LedgerTable\",\n ref: \"A2:D5\",\n columns: [{}, {}, {}, {}],\n style: {\n name: \"TableStyleMedium2\",\n },\n },\n ],\n },\n {\n name: \"Lookups\",\n rows: [\n { cells: [{ value: \"Open\" }] },\n { cells: [{ value: \"Closed\" }] },\n { cells: [{ value: \"Pending\" }] },\n ],\n },\n ],\n };\n}\n\nexport function createDuplicateTablesDocument(): SpreadsheetDocument {\n return {\n sheets: [\n {\n name: \"North\",\n rows: [\n {\n cells: [\n { value: \"Region\" },\n { value: \"Revenue\" },\n ],\n },\n {\n cells: [\n { value: \"NA\" },\n { value: 120 },\n ],\n },\n {\n cells: [\n { value: \"EMEA\" },\n { value: 180 },\n ],\n },\n ],\n tables: [\n {\n name: \"NorthTable\",\n ref: \"A1:B3\",\n columns: [{}, {}],\n },\n ],\n },\n {\n name: \"South\",\n rows: [\n {\n cells: [\n { value: \"Region\" },\n { value: \"Revenue\" },\n ],\n },\n {\n cells: [\n { value: \"APAC\" },\n { value: 90 },\n ],\n },\n {\n cells: [\n { value: \"LATAM\" },\n { value: 75 },\n ],\n },\n ],\n tables: [\n {\n name: \"SouthTable\",\n ref: \"A1:B3\",\n columns: [{}, {}],\n },\n ],\n },\n ],\n };\n}\n\nexport function createTemplateBenchmarkDocument(): SpreadsheetDocument {\n return {\n namedRanges: [\n { name: \"InvoiceHeader\", ref: \"Invoice!$B$1\" },\n { name: \"LineItems\", ref: \"Invoice!$A$4:$D$4\" },\n ],\n sheets: [\n {\n name: \"Invoice\",\n rows: [\n {\n cells: [\n { value: \"Customer\" },\n { value: \"Acme Co\" },\n ],\n },\n {\n cells: [\n { value: \"Prepared\" },\n { value: new Date(Date.UTC(2026, 2, 28)) },\n ],\n },\n {\n cells: [\n { value: \"Item\", style: \"header\" },\n { value: \"Qty\", style: \"header\" },\n { value: \"Price\", style: \"header\" },\n { value: \"Total\", style: \"header\" },\n ],\n },\n {\n cells: [\n { value: \"Starter\" },\n { value: 1 },\n { value: 10 },\n { formula: \"B4*C4\", style: \"currency\" },\n ],\n },\n {\n cells: [\n { value: \"Grand Total\" },\n { value: null },\n { value: null },\n { formula: \"SUM(D4:D4)\", style: \"currency\" },\n ],\n },\n ],\n tables: [\n {\n name: \"InvoiceTable\",\n ref: \"A3:D4\",\n columns: [{}, {}, {}, {}],\n style: {\n name: \"TableStyleMedium9\",\n },\n },\n ],\n },\n ],\n };\n}\n", "import { XMLBuilder, XMLParser } from \"fast-xml-parser\";\nimport JSZip from \"jszip\";\nimport { DETERMINISTIC_ZIP_DATE } from \"../assembly/xlsx-assembler.js\";\nimport { SpreadsheetEngine } from \"../spreadsheet-engine.js\";\nimport { XML_DECLARATION } from \"../utils/xml.js\";\nimport {\n createDuplicateTablesDocument,\n createRepairCorpusDocument,\n} from \"./workloads.js\";\n\nconst xmlParser = new XMLParser({\n ignoreAttributes: false,\n attributeNamePrefix: \"@_\",\n parseTagValue: false,\n});\n\nconst xmlBuilder = new XMLBuilder({\n ignoreAttributes: false,\n attributeNamePrefix: \"@_\",\n format: false,\n suppressEmptyNode: false,\n});\n\nfunction asArray<T>(value: T | T[] | undefined): T[] {\n if (value === undefined) {\n return [];\n }\n return Array.isArray(value) ? value : [value];\n}\n\nasync function loadZip(buffer: Buffer): Promise<JSZip> {\n return JSZip.loadAsync(buffer);\n}\n\nasync function readXml(zip: JSZip, path: string): Promise<any> {\n const file = zip.file(path);\n if (!file) {\n throw new Error(`Missing ZIP entry: ${path}`);\n }\n return xmlParser.parse(await file.async(\"string\"));\n}\n\nfunction writeXml(zip: JSZip, path: string, tree: any): void {\n zip.file(path, XML_DECLARATION + xmlBuilder.build(tree), { date: DETERMINISTIC_ZIP_DATE });\n}\n\nasync function generateZip(zip: JSZip): Promise<Buffer> {\n return zip.generateAsync({\n type: \"nodebuffer\",\n compression: \"DEFLATE\",\n compressionOptions: { level: 6 },\n mimeType: \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n });\n}\n\nfunction removeContentTypeOverride(tree: any, partName: string): boolean {\n const overrides = asArray(tree?.Types?.Override);\n const kept = overrides.filter((entry) => String(entry[\"@_PartName\"] ?? \"\") !== `/${partName}`);\n if (kept.length === overrides.length) {\n return false;\n }\n tree.Types.Override = kept;\n return true;\n}\n\nfunction firstSheetRelationshipPath(sheetNumber = 1): string {\n return `xl/worksheets/_rels/sheet${sheetNumber}.xml.rels`;\n}\n\nexport async function createRepairableCorruptionBuffer(): Promise<Buffer> {\n const base = await SpreadsheetEngine.render(createRepairCorpusDocument());\n const zip = await loadZip(base);\n\n const contentTypes = await readXml(zip, \"[Content_Types].xml\");\n removeContentTypeOverride(contentTypes, \"xl/tables/table1.xml\");\n writeXml(zip, \"[Content_Types].xml\", contentTypes);\n\n const workbook = await readXml(zip, \"xl/workbook.xml\");\n const definedNames = asArray(workbook?.workbook?.definedNames?.definedName);\n definedNames.push({\n \"@_name\": \"BrokenLedgerRef\",\n \"#text\": \"Ghost!$A$1\",\n });\n workbook.workbook.definedNames = { definedName: definedNames };\n writeXml(zip, \"xl/workbook.xml\", workbook);\n\n const sheet = await readXml(zip, \"xl/worksheets/sheet1.xml\");\n const rows = asArray(sheet?.worksheet?.sheetData?.row);\n const firstDataRow = rows.find((row) => Number(row[\"@_r\"]) === 3) ?? rows[0];\n const firstCell = asArray(firstDataRow?.c)[0];\n if (firstCell) {\n firstCell[\"@_s\"] = \"9999\";\n }\n sheet.worksheet.hyperlinks = {\n hyperlink: [\n {\n \"@_ref\": \"XFE1\",\n \"@_r:id\": \"rId2\",\n },\n ],\n };\n sheet.worksheet.dataValidations = {\n \"@_count\": \"1\",\n dataValidation: [\n {\n \"@_type\": \"list\",\n \"@_sqref\": \"A1048577\",\n formula1: \"\\\"Open,Closed,Pending\\\"\",\n },\n ],\n };\n sheet.worksheet.mergeCells = {\n \"@_count\": \"3\",\n mergeCell: [\n { \"@_ref\": \"A1:D1\" },\n { \"@_ref\": \"B1:E1\" },\n { \"@_ref\": \"XFE0:XFE1\" },\n ],\n };\n sheet.worksheet.dimension = { \"@_ref\": \"A1:A1\" };\n writeXml(zip, \"xl/worksheets/sheet1.xml\", sheet);\n\n const sheetRels = await readXml(zip, firstSheetRelationshipPath(1));\n const relationships = asArray(sheetRels?.Relationships?.Relationship);\n const tableRelationship = relationships.find((relationship) => (\n String(relationship[\"@_Type\"] ?? \"\").includes(\"/table\")\n ));\n if (tableRelationship) {\n tableRelationship[\"@_Target\"] = \"../tables/missing-table.xml\";\n }\n writeXml(zip, firstSheetRelationshipPath(1), sheetRels);\n\n const table = await readXml(zip, \"xl/tables/table1.xml\");\n if (table?.table) {\n table.table[\"@_ref\"] = \"A2:XFE1048578\";\n if (table.table.autoFilter) {\n table.table.autoFilter[\"@_ref\"] = \"A2:XFE1048578\";\n }\n }\n writeXml(zip, \"xl/tables/table1.xml\", table);\n\n return generateZip(zip);\n}\n\nexport async function createDuplicateTableCorruptionBuffer(): Promise<Buffer> {\n const base = await SpreadsheetEngine.render(createDuplicateTablesDocument());\n const zip = await loadZip(base);\n\n const secondTable = await readXml(zip, \"xl/tables/table2.xml\");\n if (secondTable?.table) {\n secondTable.table[\"@_name\"] = \"NorthTable\";\n secondTable.table[\"@_displayName\"] = \"NorthTable\";\n secondTable.table[\"@_ref\"] = \"A1:XFE1048578\";\n if (secondTable.table.autoFilter) {\n secondTable.table.autoFilter[\"@_ref\"] = \"A1:XFE1048578\";\n }\n }\n writeXml(zip, \"xl/tables/table2.xml\", secondTable);\n\n return generateZip(zip);\n}\n\nexport async function createMissingContentTypeBuffer(): Promise<Buffer> {\n const base = await SpreadsheetEngine.render(createRepairCorpusDocument());\n const zip = await loadZip(base);\n const contentTypes = await readXml(zip, \"[Content_Types].xml\");\n removeContentTypeOverride(contentTypes, \"xl/tables/table1.xml\");\n writeXml(zip, \"[Content_Types].xml\", contentTypes);\n return generateZip(zip);\n}\n\nexport async function createOrphanRelationshipBuffer(): Promise<Buffer> {\n const base = await SpreadsheetEngine.render(createRepairCorpusDocument());\n const zip = await loadZip(base);\n const sheetRels = await readXml(zip, firstSheetRelationshipPath(1));\n const relationships = asArray(sheetRels?.Relationships?.Relationship);\n const tableRelationship = relationships.find((relationship) => (\n String(relationship[\"@_Type\"] ?? \"\").includes(\"/table\")\n ));\n if (tableRelationship) {\n tableRelationship[\"@_Target\"] = \"../tables/missing-table.xml\";\n }\n writeXml(zip, firstSheetRelationshipPath(1), sheetRels);\n return generateZip(zip);\n}\n\nexport async function createStyleIndexOobBuffer(): Promise<Buffer> {\n const base = await SpreadsheetEngine.render(createRepairCorpusDocument());\n const zip = await loadZip(base);\n const sheet = await readXml(zip, \"xl/worksheets/sheet1.xml\");\n const rows = asArray(sheet?.worksheet?.sheetData?.row);\n const firstDataRow = rows.find((row) => Number(row[\"@_r\"]) === 3) ?? rows[0];\n const firstCell = asArray(firstDataRow?.c)[0];\n if (firstCell) {\n firstCell[\"@_s\"] = \"9999\";\n }\n writeXml(zip, \"xl/worksheets/sheet1.xml\", sheet);\n return generateZip(zip);\n}\n\nexport async function createHyperlinkValidationCorruptionBuffer(): Promise<Buffer> {\n const base = await SpreadsheetEngine.render(createRepairCorpusDocument());\n const zip = await loadZip(base);\n const sheet = await readXml(zip, \"xl/worksheets/sheet1.xml\");\n sheet.worksheet.hyperlinks = {\n hyperlink: [\n {\n \"@_ref\": \"XFE1\",\n \"@_r:id\": \"rId2\",\n },\n ],\n };\n sheet.worksheet.dataValidations = {\n \"@_count\": \"1\",\n dataValidation: [\n {\n \"@_type\": \"list\",\n \"@_sqref\": \"A1048577\",\n formula1: \"\\\"Open,Closed,Pending\\\"\",\n },\n ],\n };\n writeXml(zip, \"xl/worksheets/sheet1.xml\", sheet);\n return generateZip(zip);\n}\n\nexport async function createMergeDefinedNameCorruptionBuffer(): Promise<Buffer> {\n const base = await SpreadsheetEngine.render(createRepairCorpusDocument());\n const zip = await loadZip(base);\n\n const workbook = await readXml(zip, \"xl/workbook.xml\");\n const definedNames = asArray(workbook?.workbook?.definedNames?.definedName);\n definedNames.push({\n \"@_name\": \"BrokenLedgerRef\",\n \"#text\": \"Ghost!$A$1\",\n });\n workbook.workbook.definedNames = { definedName: definedNames };\n writeXml(zip, \"xl/workbook.xml\", workbook);\n\n const sheet = await readXml(zip, \"xl/worksheets/sheet1.xml\");\n sheet.worksheet.mergeCells = {\n \"@_count\": \"3\",\n mergeCell: [\n { \"@_ref\": \"A1:D1\" },\n { \"@_ref\": \"B1:E1\" },\n { \"@_ref\": \"XFE0:XFE1\" },\n ],\n };\n writeXml(zip, \"xl/worksheets/sheet1.xml\", sheet);\n\n return generateZip(zip);\n}\n\nexport async function createSharedStringIndexCorruptionBuffer(baseBuffer: Buffer): Promise<Buffer> {\n const zip = await loadZip(baseBuffer);\n const sheet = await readXml(zip, \"xl/worksheets/sheet1.xml\");\n const rows = asArray(sheet?.worksheet?.sheetData?.row);\n const firstCell = asArray(rows[0]?.c)[0];\n if (firstCell) {\n firstCell[\"@_t\"] = \"s\";\n firstCell.v = \"999999\";\n delete firstCell.is;\n }\n writeXml(zip, \"xl/worksheets/sheet1.xml\", sheet);\n return generateZip(zip);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
import {
|
|
2
|
+
cellRef,
|
|
3
|
+
parseCellRef
|
|
4
|
+
} from "./chunk-S5RMAWLC.js";
|
|
5
|
+
|
|
6
|
+
// src/quality/structural-validation.ts
|
|
7
|
+
import { XMLParser } from "fast-xml-parser";
|
|
8
|
+
import JSZip from "jszip";
|
|
9
|
+
var xmlParser = new XMLParser({
|
|
10
|
+
ignoreAttributes: false,
|
|
11
|
+
attributeNamePrefix: "@_",
|
|
12
|
+
parseTagValue: false
|
|
13
|
+
});
|
|
14
|
+
function asArray(value) {
|
|
15
|
+
if (value === void 0) {
|
|
16
|
+
return [];
|
|
17
|
+
}
|
|
18
|
+
return Array.isArray(value) ? value : [value];
|
|
19
|
+
}
|
|
20
|
+
function resolveWorksheetRowNumber(row, rowIndex) {
|
|
21
|
+
const explicit = Number(row?.["@_r"] ?? "");
|
|
22
|
+
return Number.isFinite(explicit) && explicit > 0 ? explicit : rowIndex + 1;
|
|
23
|
+
}
|
|
24
|
+
function resolveWorksheetCellRef(cell, rowNumber, cellIndex) {
|
|
25
|
+
const explicit = String(cell?.["@_r"] ?? "");
|
|
26
|
+
if (explicit) {
|
|
27
|
+
return explicit;
|
|
28
|
+
}
|
|
29
|
+
return rowNumber > 0 ? cellRef(rowNumber - 1, cellIndex) : "";
|
|
30
|
+
}
|
|
31
|
+
function addCheck(checks, name, passed, details) {
|
|
32
|
+
checks.push({ name, passed, details });
|
|
33
|
+
}
|
|
34
|
+
function getRelationshipSourceBaseSegments(relPath) {
|
|
35
|
+
if (relPath === "_rels/.rels") {
|
|
36
|
+
return [];
|
|
37
|
+
}
|
|
38
|
+
const segments = relPath.split("/");
|
|
39
|
+
const relsDirectoryIndex = segments.lastIndexOf("_rels");
|
|
40
|
+
const fileName = segments[segments.length - 1]?.replace(/\.rels$/, "");
|
|
41
|
+
const baseSegments = segments.slice(0, relsDirectoryIndex);
|
|
42
|
+
if (fileName && fileName !== ".rels") {
|
|
43
|
+
baseSegments.push(fileName);
|
|
44
|
+
}
|
|
45
|
+
return baseSegments.slice(0, -1);
|
|
46
|
+
}
|
|
47
|
+
function resolveRelationshipTarget(relPath, target) {
|
|
48
|
+
const baseSegments = getRelationshipSourceBaseSegments(relPath);
|
|
49
|
+
for (const segment of target.split("/")) {
|
|
50
|
+
if (segment === "." || segment === "") {
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
if (segment === "..") {
|
|
54
|
+
baseSegments.pop();
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
baseSegments.push(segment);
|
|
58
|
+
}
|
|
59
|
+
return baseSegments.join("/");
|
|
60
|
+
}
|
|
61
|
+
async function validateXlsxStructure(buffer) {
|
|
62
|
+
const zip = await JSZip.loadAsync(buffer);
|
|
63
|
+
const paths = Object.keys(zip.files).filter((path) => !zip.files[path]?.dir).sort();
|
|
64
|
+
const checks = [];
|
|
65
|
+
const contentTypesXml = await zip.file("[Content_Types].xml")?.async("string");
|
|
66
|
+
if (!contentTypesXml) {
|
|
67
|
+
return {
|
|
68
|
+
passed: false,
|
|
69
|
+
checks: [{ name: "content-types-present", passed: false, details: "Missing [Content_Types].xml" }]
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
const contentTypes = xmlParser.parse(contentTypesXml);
|
|
73
|
+
const overrides = asArray(contentTypes?.Types?.Override);
|
|
74
|
+
const overridePaths = new Set(overrides.map((override) => String(override["@_PartName"]).replace(/^\//, "")));
|
|
75
|
+
const nonDefaultXmlParts = paths.filter((path) => path.endsWith(".xml") && path !== "[Content_Types].xml" && path !== "_rels/.rels" && !path.endsWith(".xml.rels"));
|
|
76
|
+
const missingOverrides = nonDefaultXmlParts.filter((path) => !overridePaths.has(path));
|
|
77
|
+
const extraOverrides = [...overridePaths].filter((path) => !nonDefaultXmlParts.includes(path));
|
|
78
|
+
addCheck(
|
|
79
|
+
checks,
|
|
80
|
+
"content-types-match-zip",
|
|
81
|
+
missingOverrides.length === 0 && extraOverrides.length === 0,
|
|
82
|
+
missingOverrides.length === 0 && extraOverrides.length === 0 ? "All XML parts and overrides match" : `Missing overrides: ${missingOverrides.join(", ") || "none"}; extra overrides: ${extraOverrides.join(", ") || "none"}`
|
|
83
|
+
);
|
|
84
|
+
const relationshipPaths = paths.filter((path) => path.endsWith(".rels"));
|
|
85
|
+
for (const relPath of relationshipPaths) {
|
|
86
|
+
const relXml = await zip.file(relPath)?.async("string");
|
|
87
|
+
const rels = xmlParser.parse(relXml ?? "");
|
|
88
|
+
const relationships = asArray(rels?.Relationships?.Relationship);
|
|
89
|
+
const ids = relationships.map((relationship) => String(relationship["@_Id"]));
|
|
90
|
+
const uniqueIds = new Set(ids);
|
|
91
|
+
addCheck(
|
|
92
|
+
checks,
|
|
93
|
+
`unique-rids:${relPath}`,
|
|
94
|
+
ids.length === uniqueIds.size,
|
|
95
|
+
ids.length === uniqueIds.size ? "All relationship ids are unique" : `Duplicate relationship ids in ${relPath}`
|
|
96
|
+
);
|
|
97
|
+
const unresolved = relationships.map((relationship) => String(relationship["@_Target"])).filter((target) => !target.startsWith("http")).map((target) => resolveRelationshipTarget(relPath, target)).filter((targetPath) => !paths.includes(targetPath));
|
|
98
|
+
addCheck(
|
|
99
|
+
checks,
|
|
100
|
+
`relationship-targets:${relPath}`,
|
|
101
|
+
unresolved.length === 0,
|
|
102
|
+
unresolved.length === 0 ? "All relationship targets resolve" : `Unresolved relationship targets: ${unresolved.join(", ")}`
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
const sharedStringsXml = await zip.file("xl/sharedStrings.xml")?.async("string");
|
|
106
|
+
if (sharedStringsXml) {
|
|
107
|
+
const sharedStrings = xmlParser.parse(sharedStringsXml);
|
|
108
|
+
const root = sharedStrings?.sst;
|
|
109
|
+
const items = asArray(root?.si);
|
|
110
|
+
const declaredCount = Number(root?.["@_count"] ?? 0);
|
|
111
|
+
const declaredUniqueCount = Number(root?.["@_uniqueCount"] ?? 0);
|
|
112
|
+
let references = 0;
|
|
113
|
+
const sheetPaths2 = paths.filter((path) => /^xl\/worksheets\/sheet\d+\.xml$/.test(path));
|
|
114
|
+
for (const sheetPath of sheetPaths2) {
|
|
115
|
+
const sheetXml = await zip.file(sheetPath)?.async("string");
|
|
116
|
+
const matches = sheetXml?.match(/<c[^>]* t="s"[^>]*><v>(\d+)<\/v><\/c>/g) ?? [];
|
|
117
|
+
references += matches.length;
|
|
118
|
+
}
|
|
119
|
+
addCheck(
|
|
120
|
+
checks,
|
|
121
|
+
"shared-strings-count",
|
|
122
|
+
declaredCount === references,
|
|
123
|
+
declaredCount === references ? `Declared count matches ${references} references` : `Declared count ${declaredCount} does not match ${references} references`
|
|
124
|
+
);
|
|
125
|
+
addCheck(
|
|
126
|
+
checks,
|
|
127
|
+
"shared-strings-unique-count",
|
|
128
|
+
declaredUniqueCount === items.length,
|
|
129
|
+
declaredUniqueCount === items.length ? `Declared unique count matches ${items.length} entries` : `Declared unique count ${declaredUniqueCount} does not match ${items.length} entries`
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
const stylesXml = await zip.file("xl/styles.xml")?.async("string");
|
|
133
|
+
const styles = stylesXml ? xmlParser.parse(stylesXml) : null;
|
|
134
|
+
const cellXfs = asArray(styles?.styleSheet?.cellXfs?.xf);
|
|
135
|
+
const maxStyleIndex = Math.max(0, cellXfs.length - 1);
|
|
136
|
+
const WORKSHEET_ELEMENT_ORDER = [
|
|
137
|
+
"sheetPr",
|
|
138
|
+
"dimension",
|
|
139
|
+
"sheetViews",
|
|
140
|
+
"sheetFormatPr",
|
|
141
|
+
"cols",
|
|
142
|
+
"sheetData",
|
|
143
|
+
"sheetCalcPr",
|
|
144
|
+
"sheetProtection",
|
|
145
|
+
"protectedRanges",
|
|
146
|
+
"scenarios",
|
|
147
|
+
"autoFilter",
|
|
148
|
+
"sortState",
|
|
149
|
+
"dataConsolidate",
|
|
150
|
+
"customSheetViews",
|
|
151
|
+
"mergeCells",
|
|
152
|
+
"phoneticPr",
|
|
153
|
+
"conditionalFormatting",
|
|
154
|
+
"dataValidations",
|
|
155
|
+
"hyperlinks",
|
|
156
|
+
"printOptions",
|
|
157
|
+
"pageMargins",
|
|
158
|
+
"pageSetup",
|
|
159
|
+
"headerFooter",
|
|
160
|
+
"rowBreaks",
|
|
161
|
+
"colBreaks",
|
|
162
|
+
"customProperties",
|
|
163
|
+
"cellWatches",
|
|
164
|
+
"ignoredErrors",
|
|
165
|
+
"smartTags",
|
|
166
|
+
"drawing",
|
|
167
|
+
"legacyDrawing",
|
|
168
|
+
"legacyDrawingHF",
|
|
169
|
+
"drawingHF",
|
|
170
|
+
"picture",
|
|
171
|
+
"oleObjects",
|
|
172
|
+
"controls",
|
|
173
|
+
"webPublishItems",
|
|
174
|
+
"tableParts",
|
|
175
|
+
"extLst"
|
|
176
|
+
];
|
|
177
|
+
const elementOrderIndex = new Map(WORKSHEET_ELEMENT_ORDER.map((name, i) => [name, i]));
|
|
178
|
+
const sheetPaths = paths.filter((path) => /^xl\/worksheets\/sheet\d+\.xml$/.test(path));
|
|
179
|
+
for (const sheetPath of sheetPaths) {
|
|
180
|
+
const sheetXml = await zip.file(sheetPath)?.async("string");
|
|
181
|
+
const worksheet = xmlParser.parse(sheetXml ?? "")?.worksheet;
|
|
182
|
+
if (worksheet && sheetXml) {
|
|
183
|
+
const topLevelElements = [];
|
|
184
|
+
const tagPattern = /<(\w+)[\s>/]/g;
|
|
185
|
+
const worksheetStart = sheetXml.indexOf("<worksheet");
|
|
186
|
+
const innerXml = sheetXml.slice(worksheetStart);
|
|
187
|
+
const bodyStart = innerXml.indexOf(">") + 1;
|
|
188
|
+
const bodyEnd = innerXml.lastIndexOf("</worksheet>");
|
|
189
|
+
const body = innerXml.slice(bodyStart, bodyEnd);
|
|
190
|
+
let depth = 0;
|
|
191
|
+
const topTagPattern = /<\/?(\w+)[^>]*\/?>/g;
|
|
192
|
+
let match;
|
|
193
|
+
while ((match = topTagPattern.exec(body)) !== null) {
|
|
194
|
+
const fullMatch = match[0];
|
|
195
|
+
const tagName = match[1];
|
|
196
|
+
if (fullMatch.startsWith("</")) {
|
|
197
|
+
depth--;
|
|
198
|
+
} else if (fullMatch.endsWith("/>")) {
|
|
199
|
+
if (depth === 0) topLevelElements.push(tagName);
|
|
200
|
+
} else {
|
|
201
|
+
if (depth === 0) topLevelElements.push(tagName);
|
|
202
|
+
depth++;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
const uniqueOrdered = [];
|
|
206
|
+
for (const el of topLevelElements) {
|
|
207
|
+
if (uniqueOrdered.length === 0 || uniqueOrdered[uniqueOrdered.length - 1] !== el) {
|
|
208
|
+
uniqueOrdered.push(el);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
const knownElements = uniqueOrdered.filter((el) => elementOrderIndex.has(el));
|
|
212
|
+
let orderValid = true;
|
|
213
|
+
let orderViolation = "";
|
|
214
|
+
for (let i = 1; i < knownElements.length; i++) {
|
|
215
|
+
const prevIdx = elementOrderIndex.get(knownElements[i - 1]);
|
|
216
|
+
const currIdx = elementOrderIndex.get(knownElements[i]);
|
|
217
|
+
if (currIdx < prevIdx) {
|
|
218
|
+
orderValid = false;
|
|
219
|
+
orderViolation = `${knownElements[i]} (spec position ${currIdx}) appears after ${knownElements[i - 1]} (spec position ${prevIdx})`;
|
|
220
|
+
break;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
addCheck(
|
|
224
|
+
checks,
|
|
225
|
+
`element-order:${sheetPath}`,
|
|
226
|
+
orderValid,
|
|
227
|
+
orderValid ? "Worksheet elements follow OOXML spec order" : `Element order violation in ${sheetPath}: ${orderViolation}`
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
const rows = asArray(worksheet?.sheetData?.row);
|
|
231
|
+
const rowNumbers = rows.map((row, index) => resolveWorksheetRowNumber(row, index));
|
|
232
|
+
const rowsAscending = rowNumbers.every((rowNumber, index) => index === 0 || rowNumbers[index - 1] < rowNumber);
|
|
233
|
+
addCheck(
|
|
234
|
+
checks,
|
|
235
|
+
`rows-ascending:${sheetPath}`,
|
|
236
|
+
rowsAscending,
|
|
237
|
+
rowsAscending ? "Rows are strictly ascending" : `Row order violation in ${sheetPath}`
|
|
238
|
+
);
|
|
239
|
+
let cellOrderValid = true;
|
|
240
|
+
let styleIndicesValid = true;
|
|
241
|
+
let sharedStringIndicesValid = true;
|
|
242
|
+
rows.forEach((row, rowIndex) => {
|
|
243
|
+
const cells = asArray(row.c);
|
|
244
|
+
const rowNumber = resolveWorksheetRowNumber(row, rowIndex);
|
|
245
|
+
const refs = cells.map((cell, cellIndex) => parseCellRef(resolveWorksheetCellRef(cell, rowNumber, cellIndex)));
|
|
246
|
+
cellOrderValid = cellOrderValid && refs.every((ref, index) => index === 0 || refs[index - 1].col < ref.col);
|
|
247
|
+
for (const cell of cells) {
|
|
248
|
+
const styleIndex = cell["@_s"];
|
|
249
|
+
if (styleIndex !== void 0 && Number(styleIndex) > maxStyleIndex) {
|
|
250
|
+
styleIndicesValid = false;
|
|
251
|
+
}
|
|
252
|
+
if (cell["@_t"] === "s") {
|
|
253
|
+
const sharedIndex = Number(cell.v);
|
|
254
|
+
const sharedStrings = sharedStringsXml ? xmlParser.parse(sharedStringsXml)?.sst : null;
|
|
255
|
+
const uniqueCount = Number(sharedStrings?.["@_uniqueCount"] ?? 0);
|
|
256
|
+
if (!(sharedIndex >= 0 && sharedIndex < uniqueCount)) {
|
|
257
|
+
sharedStringIndicesValid = false;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
addCheck(
|
|
263
|
+
checks,
|
|
264
|
+
`cells-ascending:${sheetPath}`,
|
|
265
|
+
cellOrderValid,
|
|
266
|
+
cellOrderValid ? "Cells are strictly ascending within each row" : `Cell order violation in ${sheetPath}`
|
|
267
|
+
);
|
|
268
|
+
addCheck(
|
|
269
|
+
checks,
|
|
270
|
+
`style-indices:${sheetPath}`,
|
|
271
|
+
styleIndicesValid,
|
|
272
|
+
styleIndicesValid ? `Style indices are within 0..${maxStyleIndex}` : `Style index out of range in ${sheetPath}`
|
|
273
|
+
);
|
|
274
|
+
addCheck(
|
|
275
|
+
checks,
|
|
276
|
+
`shared-string-indices:${sheetPath}`,
|
|
277
|
+
sharedStringIndicesValid,
|
|
278
|
+
sharedStringIndicesValid ? "Shared string references are in range" : `Shared string reference out of range in ${sheetPath}`
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
return {
|
|
282
|
+
passed: checks.every((check) => check.passed),
|
|
283
|
+
checks
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
export {
|
|
288
|
+
validateXlsxStructure
|
|
289
|
+
};
|
|
290
|
+
//# sourceMappingURL=chunk-PQSLPEN5.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/quality/structural-validation.ts"],
|
|
4
|
+
"sourcesContent": ["import { XMLParser } from \"fast-xml-parser\";\nimport JSZip from \"jszip\";\nimport { cellRef, parseCellRef } from \"../utils/cell-ref.js\";\n\nexport interface StructuralValidationCheck {\n name: string;\n passed: boolean;\n details: string;\n}\n\nexport interface StructuralValidationSummary {\n passed: boolean;\n checks: StructuralValidationCheck[];\n}\n\nconst xmlParser = new XMLParser({\n ignoreAttributes: false,\n attributeNamePrefix: \"@_\",\n parseTagValue: false,\n});\n\nfunction asArray<T>(value: T | T[] | undefined): T[] {\n if (value === undefined) {\n return [];\n }\n return Array.isArray(value) ? value : [value];\n}\n\nfunction resolveWorksheetRowNumber(row: any, rowIndex: number): number {\n const explicit = Number(row?.[\"@_r\"] ?? \"\");\n return Number.isFinite(explicit) && explicit > 0 ? explicit : rowIndex + 1;\n}\n\nfunction resolveWorksheetCellRef(cell: any, rowNumber: number, cellIndex: number): string {\n const explicit = String(cell?.[\"@_r\"] ?? \"\");\n if (explicit) {\n return explicit;\n }\n return rowNumber > 0 ? cellRef(rowNumber - 1, cellIndex) : \"\";\n}\n\nfunction addCheck(checks: StructuralValidationCheck[], name: string, passed: boolean, details: string): void {\n checks.push({ name, passed, details });\n}\n\nfunction getRelationshipSourceBaseSegments(relPath: string): string[] {\n if (relPath === \"_rels/.rels\") {\n return [];\n }\n\n const segments = relPath.split(\"/\");\n const relsDirectoryIndex = segments.lastIndexOf(\"_rels\");\n const fileName = segments[segments.length - 1]?.replace(/\\.rels$/, \"\");\n const baseSegments = segments.slice(0, relsDirectoryIndex);\n\n if (fileName && fileName !== \".rels\") {\n baseSegments.push(fileName);\n }\n\n return baseSegments.slice(0, -1);\n}\n\nfunction resolveRelationshipTarget(relPath: string, target: string): string {\n const baseSegments = getRelationshipSourceBaseSegments(relPath);\n for (const segment of target.split(\"/\")) {\n if (segment === \".\" || segment === \"\") {\n continue;\n }\n if (segment === \"..\") {\n baseSegments.pop();\n continue;\n }\n baseSegments.push(segment);\n }\n return baseSegments.join(\"/\");\n}\n\nexport async function validateXlsxStructure(buffer: Buffer): Promise<StructuralValidationSummary> {\n const zip = await JSZip.loadAsync(buffer);\n const paths = Object.keys(zip.files).filter((path) => !zip.files[path]?.dir).sort();\n const checks: StructuralValidationCheck[] = [];\n const contentTypesXml = await zip.file(\"[Content_Types].xml\")?.async(\"string\");\n\n if (!contentTypesXml) {\n return {\n passed: false,\n checks: [{ name: \"content-types-present\", passed: false, details: \"Missing [Content_Types].xml\" }],\n };\n }\n\n const contentTypes = xmlParser.parse(contentTypesXml);\n const overrides = asArray(contentTypes?.Types?.Override);\n const overridePaths = new Set(overrides.map((override) => String(override[\"@_PartName\"]).replace(/^\\//, \"\")));\n\n const nonDefaultXmlParts = paths.filter((path) => path.endsWith(\".xml\") && path !== \"[Content_Types].xml\" && path !== \"_rels/.rels\" && !path.endsWith(\".xml.rels\"));\n const missingOverrides = nonDefaultXmlParts.filter((path) => !overridePaths.has(path));\n const extraOverrides = [...overridePaths].filter((path) => !nonDefaultXmlParts.includes(path));\n addCheck(\n checks,\n \"content-types-match-zip\",\n missingOverrides.length === 0 && extraOverrides.length === 0,\n missingOverrides.length === 0 && extraOverrides.length === 0\n ? \"All XML parts and overrides match\"\n : `Missing overrides: ${missingOverrides.join(\", \") || \"none\"}; extra overrides: ${extraOverrides.join(\", \") || \"none\"}`,\n );\n\n const relationshipPaths = paths.filter((path) => path.endsWith(\".rels\"));\n for (const relPath of relationshipPaths) {\n const relXml = await zip.file(relPath)?.async(\"string\");\n const rels = xmlParser.parse(relXml ?? \"\");\n const relationships = asArray(rels?.Relationships?.Relationship);\n const ids = relationships.map((relationship) => String(relationship[\"@_Id\"]));\n const uniqueIds = new Set(ids);\n addCheck(\n checks,\n `unique-rids:${relPath}`,\n ids.length === uniqueIds.size,\n ids.length === uniqueIds.size ? \"All relationship ids are unique\" : `Duplicate relationship ids in ${relPath}`,\n );\n\n const unresolved = relationships\n .map((relationship) => String(relationship[\"@_Target\"]))\n .filter((target) => !target.startsWith(\"http\"))\n .map((target) => resolveRelationshipTarget(relPath, target))\n .filter((targetPath) => !paths.includes(targetPath));\n addCheck(\n checks,\n `relationship-targets:${relPath}`,\n unresolved.length === 0,\n unresolved.length === 0 ? \"All relationship targets resolve\" : `Unresolved relationship targets: ${unresolved.join(\", \")}`,\n );\n }\n\n const sharedStringsXml = await zip.file(\"xl/sharedStrings.xml\")?.async(\"string\");\n if (sharedStringsXml) {\n const sharedStrings = xmlParser.parse(sharedStringsXml);\n const root = sharedStrings?.sst;\n const items = asArray(root?.si);\n const declaredCount = Number(root?.[\"@_count\"] ?? 0);\n const declaredUniqueCount = Number(root?.[\"@_uniqueCount\"] ?? 0);\n let references = 0;\n const sheetPaths = paths.filter((path) => /^xl\\/worksheets\\/sheet\\d+\\.xml$/.test(path));\n for (const sheetPath of sheetPaths) {\n const sheetXml = await zip.file(sheetPath)?.async(\"string\");\n const matches = sheetXml?.match(/<c[^>]* t=\"s\"[^>]*><v>(\\d+)<\\/v><\\/c>/g) ?? [];\n references += matches.length;\n }\n addCheck(\n checks,\n \"shared-strings-count\",\n declaredCount === references,\n declaredCount === references ? `Declared count matches ${references} references` : `Declared count ${declaredCount} does not match ${references} references`,\n );\n addCheck(\n checks,\n \"shared-strings-unique-count\",\n declaredUniqueCount === items.length,\n declaredUniqueCount === items.length ? `Declared unique count matches ${items.length} entries` : `Declared unique count ${declaredUniqueCount} does not match ${items.length} entries`,\n );\n }\n\n const stylesXml = await zip.file(\"xl/styles.xml\")?.async(\"string\");\n const styles = stylesXml ? xmlParser.parse(stylesXml) : null;\n const cellXfs = asArray(styles?.styleSheet?.cellXfs?.xf);\n const maxStyleIndex = Math.max(0, cellXfs.length - 1);\n\n // OOXML CT_Worksheet element ordering (ECMA-376 Part 1, \u00A718.3.1.99)\n const WORKSHEET_ELEMENT_ORDER: string[] = [\n \"sheetPr\", \"dimension\", \"sheetViews\", \"sheetFormatPr\", \"cols\", \"sheetData\",\n \"sheetCalcPr\", \"sheetProtection\", \"protectedRanges\", \"scenarios\", \"autoFilter\",\n \"sortState\", \"dataConsolidate\", \"customSheetViews\", \"mergeCells\", \"phoneticPr\",\n \"conditionalFormatting\", \"dataValidations\", \"hyperlinks\", \"printOptions\",\n \"pageMargins\", \"pageSetup\", \"headerFooter\", \"rowBreaks\", \"colBreaks\",\n \"customProperties\", \"cellWatches\", \"ignoredErrors\", \"smartTags\",\n \"drawing\", \"legacyDrawing\", \"legacyDrawingHF\", \"drawingHF\", \"picture\",\n \"oleObjects\", \"controls\", \"webPublishItems\", \"tableParts\", \"extLst\",\n ];\n const elementOrderIndex = new Map(WORKSHEET_ELEMENT_ORDER.map((name, i) => [name, i]));\n\n const sheetPaths = paths.filter((path) => /^xl\\/worksheets\\/sheet\\d+\\.xml$/.test(path));\n for (const sheetPath of sheetPaths) {\n const sheetXml = await zip.file(sheetPath)?.async(\"string\");\n const worksheet = xmlParser.parse(sheetXml ?? \"\")?.worksheet;\n\n // Check element ordering against OOXML spec\n if (worksheet && sheetXml) {\n const topLevelElements: string[] = [];\n const tagPattern = /<(\\w+)[\\s>/]/g;\n const worksheetStart = sheetXml.indexOf(\"<worksheet\");\n const innerXml = sheetXml.slice(worksheetStart);\n // Extract direct children of <worksheet> by finding tags after the root open\n const bodyStart = innerXml.indexOf(\">\") + 1;\n const bodyEnd = innerXml.lastIndexOf(\"</worksheet>\");\n const body = innerXml.slice(bodyStart, bodyEnd);\n // Find top-level element names (skip nested by tracking depth)\n let depth = 0;\n const topTagPattern = /<\\/?(\\w+)[^>]*\\/?>/g;\n let match: RegExpExecArray | null;\n while ((match = topTagPattern.exec(body)) !== null) {\n const fullMatch = match[0];\n const tagName = match[1];\n if (fullMatch.startsWith(\"</\")) {\n depth--;\n } else if (fullMatch.endsWith(\"/>\")) {\n if (depth === 0) topLevelElements.push(tagName);\n } else {\n if (depth === 0) topLevelElements.push(tagName);\n depth++;\n }\n }\n // Deduplicate consecutive repeats (e.g., multiple conditionalFormatting)\n const uniqueOrdered: string[] = [];\n for (const el of topLevelElements) {\n if (uniqueOrdered.length === 0 || uniqueOrdered[uniqueOrdered.length - 1] !== el) {\n uniqueOrdered.push(el);\n }\n }\n // Check ordering\n const knownElements = uniqueOrdered.filter((el) => elementOrderIndex.has(el));\n let orderValid = true;\n let orderViolation = \"\";\n for (let i = 1; i < knownElements.length; i++) {\n const prevIdx = elementOrderIndex.get(knownElements[i - 1]!)!;\n const currIdx = elementOrderIndex.get(knownElements[i]!)!;\n if (currIdx < prevIdx) {\n orderValid = false;\n orderViolation = `${knownElements[i]} (spec position ${currIdx}) appears after ${knownElements[i - 1]} (spec position ${prevIdx})`;\n break;\n }\n }\n addCheck(\n checks,\n `element-order:${sheetPath}`,\n orderValid,\n orderValid ? \"Worksheet elements follow OOXML spec order\" : `Element order violation in ${sheetPath}: ${orderViolation}`,\n );\n }\n const rows = asArray(worksheet?.sheetData?.row);\n const rowNumbers = rows.map((row, index) => resolveWorksheetRowNumber(row, index));\n const rowsAscending = rowNumbers.every((rowNumber, index) => index === 0 || rowNumbers[index - 1] < rowNumber);\n addCheck(\n checks,\n `rows-ascending:${sheetPath}`,\n rowsAscending,\n rowsAscending ? \"Rows are strictly ascending\" : `Row order violation in ${sheetPath}`,\n );\n\n let cellOrderValid = true;\n let styleIndicesValid = true;\n let sharedStringIndicesValid = true;\n\n rows.forEach((row, rowIndex) => {\n const cells = asArray(row.c);\n const rowNumber = resolveWorksheetRowNumber(row, rowIndex);\n const refs = cells.map((cell, cellIndex) => parseCellRef(resolveWorksheetCellRef(cell, rowNumber, cellIndex)));\n cellOrderValid = cellOrderValid && refs.every((ref, index) => index === 0 || refs[index - 1].col < ref.col);\n\n for (const cell of cells) {\n const styleIndex = cell[\"@_s\"];\n if (styleIndex !== undefined && Number(styleIndex) > maxStyleIndex) {\n styleIndicesValid = false;\n }\n if (cell[\"@_t\"] === \"s\") {\n const sharedIndex = Number(cell.v);\n const sharedStrings = sharedStringsXml ? xmlParser.parse(sharedStringsXml)?.sst : null;\n const uniqueCount = Number(sharedStrings?.[\"@_uniqueCount\"] ?? 0);\n if (!(sharedIndex >= 0 && sharedIndex < uniqueCount)) {\n sharedStringIndicesValid = false;\n }\n }\n }\n });\n\n addCheck(\n checks,\n `cells-ascending:${sheetPath}`,\n cellOrderValid,\n cellOrderValid ? \"Cells are strictly ascending within each row\" : `Cell order violation in ${sheetPath}`,\n );\n addCheck(\n checks,\n `style-indices:${sheetPath}`,\n styleIndicesValid,\n styleIndicesValid ? `Style indices are within 0..${maxStyleIndex}` : `Style index out of range in ${sheetPath}`,\n );\n addCheck(\n checks,\n `shared-string-indices:${sheetPath}`,\n sharedStringIndicesValid,\n sharedStringIndicesValid ? \"Shared string references are in range\" : `Shared string reference out of range in ${sheetPath}`,\n );\n }\n\n return {\n passed: checks.every((check) => check.passed),\n checks,\n };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["sheetPaths"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import {
|
|
2
|
+
validateXlsxStructure
|
|
3
|
+
} from "./chunk-PQSLPEN5.js";
|
|
4
|
+
import {
|
|
5
|
+
SpreadsheetEngine,
|
|
6
|
+
getPhase1Fixture
|
|
7
|
+
} from "./chunk-S5RMAWLC.js";
|
|
8
|
+
|
|
9
|
+
// src/benchmarks/report.ts
|
|
10
|
+
import { performance } from "node:perf_hooks";
|
|
11
|
+
import process from "node:process";
|
|
12
|
+
function percentile(sorted, point) {
|
|
13
|
+
if (sorted.length === 0) {
|
|
14
|
+
return 0;
|
|
15
|
+
}
|
|
16
|
+
const position = Math.min(sorted.length - 1, Math.max(0, Math.ceil(point / 100 * sorted.length) - 1));
|
|
17
|
+
return sorted[position];
|
|
18
|
+
}
|
|
19
|
+
function summarize(durations) {
|
|
20
|
+
const sorted = [...durations].sort((left, right) => left - right);
|
|
21
|
+
return {
|
|
22
|
+
p50: percentile(sorted, 50),
|
|
23
|
+
p95: percentile(sorted, 95),
|
|
24
|
+
max: sorted[sorted.length - 1] ?? 0
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function maybeGc() {
|
|
28
|
+
if (typeof global.gc === "function") {
|
|
29
|
+
global.gc();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
async function runRenderBenchmark(fixtureName, iterations = 10) {
|
|
33
|
+
const fixture = getPhase1Fixture(fixtureName);
|
|
34
|
+
const durations = [];
|
|
35
|
+
let fileSizeBytes = 0;
|
|
36
|
+
const initialRss = process.memoryUsage().rss;
|
|
37
|
+
for (let index = 0; index < iterations; index += 1) {
|
|
38
|
+
maybeGc();
|
|
39
|
+
const start = performance.now();
|
|
40
|
+
const buffer = await SpreadsheetEngine.render(fixture.document);
|
|
41
|
+
const elapsed = performance.now() - start;
|
|
42
|
+
durations.push(elapsed);
|
|
43
|
+
fileSizeBytes = buffer.length;
|
|
44
|
+
}
|
|
45
|
+
const rssDeltaBytes = Math.max(0, process.memoryUsage().rss - initialRss);
|
|
46
|
+
const stats = summarize(durations);
|
|
47
|
+
const cells = fixture.rows * fixture.cols;
|
|
48
|
+
return {
|
|
49
|
+
name: fixtureName,
|
|
50
|
+
stats,
|
|
51
|
+
rowsPerSecond: fixture.rows / (stats.p95 / 1e3),
|
|
52
|
+
cellsPerSecond: cells / (stats.p95 / 1e3),
|
|
53
|
+
fileSizeBytes,
|
|
54
|
+
rssDeltaBytes
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
async function runCorrectnessSweep() {
|
|
58
|
+
const fixtureNames = [
|
|
59
|
+
"empty",
|
|
60
|
+
"single-cell",
|
|
61
|
+
"types-mixed",
|
|
62
|
+
"types-edge",
|
|
63
|
+
"strings-unicode",
|
|
64
|
+
"strings-xml-hostile",
|
|
65
|
+
"strings-whitespace",
|
|
66
|
+
"dates-range",
|
|
67
|
+
"multi-sheet",
|
|
68
|
+
"sheet-names",
|
|
69
|
+
"columns-width",
|
|
70
|
+
"rows-hidden",
|
|
71
|
+
"medium",
|
|
72
|
+
"determinism-seed"
|
|
73
|
+
];
|
|
74
|
+
const failures = [];
|
|
75
|
+
for (const fixtureName of fixtureNames) {
|
|
76
|
+
const fixture = getPhase1Fixture(fixtureName);
|
|
77
|
+
maybeGc();
|
|
78
|
+
const [first, second] = await Promise.all([
|
|
79
|
+
SpreadsheetEngine.render(fixture.document),
|
|
80
|
+
SpreadsheetEngine.render(fixture.document)
|
|
81
|
+
]);
|
|
82
|
+
const validation = await validateXlsxStructure(first);
|
|
83
|
+
if (!validation.passed) {
|
|
84
|
+
failures.push(`${fixtureName}: ${validation.checks.filter((check) => !check.passed).map((check) => check.name).join(", ")}`);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
if (Buffer.compare(first, second) !== 0) {
|
|
88
|
+
failures.push(`${fixtureName}: deterministic render mismatch`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
passed: fixtureNames.length - failures.length,
|
|
93
|
+
total: fixtureNames.length,
|
|
94
|
+
failures
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
async function renderPhase1BenchmarkReport(iterations = 10) {
|
|
98
|
+
const correctness = await runCorrectnessSweep();
|
|
99
|
+
const benchmarkNames = ["large-10k", "large-50k", "large-100k"];
|
|
100
|
+
const results = [];
|
|
101
|
+
for (const benchmarkName of benchmarkNames) {
|
|
102
|
+
results.push(await runRenderBenchmark(benchmarkName, iterations));
|
|
103
|
+
}
|
|
104
|
+
const lines = [
|
|
105
|
+
"\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550",
|
|
106
|
+
" PaperJSX XLSX Engine \u2014 Phase 1 Local Benchmark Report",
|
|
107
|
+
` Node.js ${process.version} | ${process.platform} ${process.arch}`,
|
|
108
|
+
"\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550",
|
|
109
|
+
"",
|
|
110
|
+
` STRUCTURAL CORRECTNESS (${correctness.passed}/${correctness.total} passing)`
|
|
111
|
+
];
|
|
112
|
+
if (correctness.failures.length === 0) {
|
|
113
|
+
lines.push(" \u2713 All structural fixture renders passed deterministic validation");
|
|
114
|
+
} else {
|
|
115
|
+
for (const failure of correctness.failures) {
|
|
116
|
+
lines.push(` \u2717 ${failure}`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
lines.push("");
|
|
120
|
+
lines.push(" PERFORMANCE");
|
|
121
|
+
lines.push(" p50 p95 max rows/sec cells/sec file size");
|
|
122
|
+
for (const result of results) {
|
|
123
|
+
lines.push(
|
|
124
|
+
` ${result.name.padEnd(12)} ${result.stats.p50.toFixed(0).padStart(5)}ms ${result.stats.p95.toFixed(0).padStart(7)}ms ${result.stats.max.toFixed(0).padStart(7)}ms ${result.rowsPerSecond.toFixed(0).padStart(12)} ${result.cellsPerSecond.toFixed(0).padStart(13)} ${String(result.fileSizeBytes).padStart(11)}`
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
lines.push("");
|
|
128
|
+
lines.push(" MEMORY");
|
|
129
|
+
for (const result of results) {
|
|
130
|
+
lines.push(` ${result.name.padEnd(12)} RSS delta ${Math.round(result.rssDeltaBytes / (1024 * 1024))} MB`);
|
|
131
|
+
}
|
|
132
|
+
lines.push("");
|
|
133
|
+
lines.push("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
|
|
134
|
+
return lines.join("\n");
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export {
|
|
138
|
+
runRenderBenchmark,
|
|
139
|
+
runCorrectnessSweep,
|
|
140
|
+
renderPhase1BenchmarkReport
|
|
141
|
+
};
|
|
142
|
+
//# sourceMappingURL=chunk-QDWDSM74.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/benchmarks/report.ts"],
|
|
4
|
+
"sourcesContent": ["import { performance } from \"node:perf_hooks\";\nimport process from \"node:process\";\nimport { SpreadsheetEngine } from \"../spreadsheet-engine.js\";\nimport { getPhase1Fixture } from \"../fixtures/phase1.js\";\nimport { validateXlsxStructure } from \"../quality/structural-validation.js\";\n\nexport interface BenchmarkStats {\n p50: number;\n p95: number;\n max: number;\n}\n\nexport interface Phase1BenchmarkResult {\n name: string;\n stats: BenchmarkStats;\n rowsPerSecond: number;\n cellsPerSecond: number;\n fileSizeBytes: number;\n rssDeltaBytes: number;\n}\n\nfunction percentile(sorted: number[], point: number): number {\n if (sorted.length === 0) {\n return 0;\n }\n const position = Math.min(sorted.length - 1, Math.max(0, Math.ceil((point / 100) * sorted.length) - 1));\n return sorted[position];\n}\n\nfunction summarize(durations: number[]): BenchmarkStats {\n const sorted = [...durations].sort((left, right) => left - right);\n return {\n p50: percentile(sorted, 50),\n p95: percentile(sorted, 95),\n max: sorted[sorted.length - 1] ?? 0,\n };\n}\n\nfunction maybeGc(): void {\n if (typeof global.gc === \"function\") {\n global.gc();\n }\n}\n\nexport async function runRenderBenchmark(\n fixtureName: \"large-10k\" | \"large-50k\" | \"large-100k\",\n iterations = 10,\n): Promise<Phase1BenchmarkResult> {\n const fixture = getPhase1Fixture(fixtureName);\n const durations: number[] = [];\n let fileSizeBytes = 0;\n const initialRss = process.memoryUsage().rss;\n\n for (let index = 0; index < iterations; index += 1) {\n maybeGc();\n const start = performance.now();\n const buffer = await SpreadsheetEngine.render(fixture.document);\n const elapsed = performance.now() - start;\n durations.push(elapsed);\n fileSizeBytes = buffer.length;\n }\n\n const rssDeltaBytes = Math.max(0, process.memoryUsage().rss - initialRss);\n const stats = summarize(durations);\n const cells = fixture.rows * fixture.cols;\n\n return {\n name: fixtureName,\n stats,\n rowsPerSecond: fixture.rows / (stats.p95 / 1000),\n cellsPerSecond: cells / (stats.p95 / 1000),\n fileSizeBytes,\n rssDeltaBytes,\n };\n}\n\nexport async function runCorrectnessSweep(): Promise<{ passed: number; total: number; failures: string[] }> {\n const fixtureNames = [\n \"empty\",\n \"single-cell\",\n \"types-mixed\",\n \"types-edge\",\n \"strings-unicode\",\n \"strings-xml-hostile\",\n \"strings-whitespace\",\n \"dates-range\",\n \"multi-sheet\",\n \"sheet-names\",\n \"columns-width\",\n \"rows-hidden\",\n \"medium\",\n \"determinism-seed\",\n ] as const;\n\n const failures: string[] = [];\n for (const fixtureName of fixtureNames) {\n const fixture = getPhase1Fixture(fixtureName);\n maybeGc();\n const [first, second] = await Promise.all([\n SpreadsheetEngine.render(fixture.document),\n SpreadsheetEngine.render(fixture.document),\n ]);\n const validation = await validateXlsxStructure(first);\n if (!validation.passed) {\n failures.push(`${fixtureName}: ${validation.checks.filter((check) => !check.passed).map((check) => check.name).join(\", \")}`);\n continue;\n }\n if (Buffer.compare(first, second) !== 0) {\n failures.push(`${fixtureName}: deterministic render mismatch`);\n }\n }\n\n return {\n passed: fixtureNames.length - failures.length,\n total: fixtureNames.length,\n failures,\n };\n}\n\nexport async function renderPhase1BenchmarkReport(iterations = 10): Promise<string> {\n const correctness = await runCorrectnessSweep();\n const benchmarkNames = [\"large-10k\", \"large-50k\", \"large-100k\"] as const;\n const results = [];\n for (const benchmarkName of benchmarkNames) {\n results.push(await runRenderBenchmark(benchmarkName, iterations));\n }\n\n const lines: string[] = [\n \"\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\",\n \" PaperJSX XLSX Engine \u2014 Phase 1 Local Benchmark Report\",\n ` Node.js ${process.version} | ${process.platform} ${process.arch}`,\n \"\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\",\n \"\",\n ` STRUCTURAL CORRECTNESS (${correctness.passed}/${correctness.total} passing)`,\n ];\n\n if (correctness.failures.length === 0) {\n lines.push(\" \u2713 All structural fixture renders passed deterministic validation\");\n } else {\n for (const failure of correctness.failures) {\n lines.push(` \u2717 ${failure}`);\n }\n }\n\n lines.push(\"\");\n lines.push(\" PERFORMANCE\");\n lines.push(\" p50 p95 max rows/sec cells/sec file size\");\n for (const result of results) {\n lines.push(\n ` ${result.name.padEnd(12)} ${result.stats.p50.toFixed(0).padStart(5)}ms ${result.stats.p95.toFixed(0).padStart(7)}ms ${result.stats.max.toFixed(0).padStart(7)}ms ${result.rowsPerSecond.toFixed(0).padStart(12)} ${result.cellsPerSecond.toFixed(0).padStart(13)} ${String(result.fileSizeBytes).padStart(11)}`,\n );\n }\n\n lines.push(\"\");\n lines.push(\" MEMORY\");\n for (const result of results) {\n lines.push(` ${result.name.padEnd(12)} RSS delta ${Math.round(result.rssDeltaBytes / (1024 * 1024))} MB`);\n }\n lines.push(\"\");\n lines.push(\"\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\");\n\n return lines.join(\"\\n\");\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|