juxscript 1.1.198 → 1.1.200

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.
@@ -88,7 +88,8 @@ export declare class TabularDriver {
88
88
  */
89
89
  fetch(url: string, options?: ParseOptions): Promise<DataFrame>;
90
90
  /**
91
- * ✅ UPDATED: Stream Excel file with optional headerRow override
91
+ * ✅ FIXED: Stream Excel file with optional headerRow override
92
+ * headerRow is 0-based: 0 = first row, 1 = second row, etc.
92
93
  */
93
94
  streamFileMultiSheet(file: File, options?: ParseOptions): Promise<Record<string, DataFrame>>;
94
95
  private _splitLines;
@@ -1 +1 @@
1
- {"version":3,"file":"TabularDriver.d.ts","sourceRoot":"","sources":["TabularDriver.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TabularDriver.d.ts","sourceRoot":"","sources":["TabularDriver.ts"],"names":[],"mappings":"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"}
@@ -487,10 +487,11 @@ export class TabularDriver {
487
487
  return df;
488
488
  }
489
489
  /**
490
- * ✅ UPDATED: Stream Excel file with optional headerRow override
490
+ * ✅ FIXED: Stream Excel file with optional headerRow override
491
+ * headerRow is 0-based: 0 = first row, 1 = second row, etc.
491
492
  */
492
493
  async streamFileMultiSheet(file, options = {}) {
493
- const { maxSheetSize = 100000, sheetChunkSize = 10000, onProgress, headerRow } = options;
494
+ const { maxSheetSize = 100000, sheetChunkSize = 10000, onProgress, headerRow = 0 } = options;
494
495
  let XLSX;
495
496
  try {
496
497
  XLSX = await import('xlsx');
@@ -524,17 +525,58 @@ export class TabularDriver {
524
525
  processedSheets++;
525
526
  continue;
526
527
  }
527
- // When headerRow is specified and > 0, we need to:
528
- // 1. Tell sheet_to_json to start reading from that row
529
- // 2. SheetJS treats the first row of the range as headers
530
- const jsonData = XLSX.utils.sheet_to_json(worksheet, {
531
- range: (headerRow !== undefined && headerRow > 0) ? headerRow : undefined,
528
+ // Always get raw data as array of arrays (no header interpretation)
529
+ const rawData = XLSX.utils.sheet_to_json(worksheet, {
530
+ header: 1, // Return array of arrays
532
531
  defval: null,
533
532
  raw: false,
534
- blankrows: false
533
+ blankrows: true // Keep blank rows to preserve row indices
535
534
  });
536
- if (jsonData.length > 0) {
537
- sheets[sheetName] = new DataFrame(jsonData);
535
+ if (rawData.length === 0) {
536
+ processedSheets++;
537
+ continue;
538
+ }
539
+ // Validate headerRow is within bounds
540
+ if (headerRow >= rawData.length) {
541
+ console.warn(`[TabularDriver] headerRow ${headerRow} exceeds data length ${rawData.length}, using 0`);
542
+ processedSheets++;
543
+ continue;
544
+ }
545
+ // Extract headers from the specified row (0-based index)
546
+ const headerRowData = rawData[headerRow] || [];
547
+ const headers = headerRowData.map((h, i) => {
548
+ if (h === null || h === undefined || String(h).trim() === '') {
549
+ return `__EMPTY${i > 0 ? '_' + i : ''}`;
550
+ }
551
+ return String(h).trim();
552
+ });
553
+ // Ensure we have at least one valid header
554
+ if (headers.length === 0 || headers.every((h) => h.startsWith('__EMPTY'))) {
555
+ console.warn(`[TabularDriver] No valid headers found at row ${headerRow}`);
556
+ processedSheets++;
557
+ continue;
558
+ }
559
+ // Build rows from data AFTER the header row
560
+ const rows = [];
561
+ for (let i = headerRow + 1; i < rawData.length; i++) {
562
+ const rowData = rawData[i];
563
+ // Skip completely empty rows
564
+ if (!rowData || rowData.length === 0) {
565
+ continue;
566
+ }
567
+ // Skip rows where all cells are null/undefined/empty
568
+ const hasContent = rowData.some((cell) => cell !== null && cell !== undefined && String(cell).trim() !== '');
569
+ if (!hasContent) {
570
+ continue;
571
+ }
572
+ const row = {};
573
+ headers.forEach((header, j) => {
574
+ row[header] = rowData[j] !== undefined ? rowData[j] : null;
575
+ });
576
+ rows.push(row);
577
+ }
578
+ if (rows.length > 0) {
579
+ sheets[sheetName] = new DataFrame(rows);
538
580
  }
539
581
  processedSheets++;
540
582
  if (onProgress) {
@@ -607,10 +607,11 @@ export class TabularDriver {
607
607
  }
608
608
 
609
609
  /**
610
- * ✅ UPDATED: Stream Excel file with optional headerRow override
610
+ * ✅ FIXED: Stream Excel file with optional headerRow override
611
+ * headerRow is 0-based: 0 = first row, 1 = second row, etc.
611
612
  */
612
613
  async streamFileMultiSheet(file: File, options: ParseOptions = {}): Promise<Record<string, DataFrame>> {
613
- const { maxSheetSize = 100000, sheetChunkSize = 10000, onProgress, headerRow } = options;
614
+ const { maxSheetSize = 100000, sheetChunkSize = 10000, onProgress, headerRow = 0 } = options;
614
615
 
615
616
  let XLSX: any;
616
617
  try {
@@ -652,18 +653,69 @@ export class TabularDriver {
652
653
  continue;
653
654
  }
654
655
 
655
- // When headerRow is specified and > 0, we need to:
656
- // 1. Tell sheet_to_json to start reading from that row
657
- // 2. SheetJS treats the first row of the range as headers
658
- const jsonData: Record<string, any>[] = XLSX.utils.sheet_to_json(worksheet, {
659
- range: (headerRow !== undefined && headerRow > 0) ? headerRow : undefined,
656
+ // Always get raw data as array of arrays (no header interpretation)
657
+ const rawData: any[][] = XLSX.utils.sheet_to_json(worksheet, {
658
+ header: 1, // Return array of arrays
660
659
  defval: null,
661
660
  raw: false,
662
- blankrows: false
661
+ blankrows: true // Keep blank rows to preserve row indices
663
662
  });
664
663
 
665
- if (jsonData.length > 0) {
666
- sheets[sheetName] = new DataFrame(jsonData);
664
+ if (rawData.length === 0) {
665
+ processedSheets++;
666
+ continue;
667
+ }
668
+
669
+ // Validate headerRow is within bounds
670
+ if (headerRow >= rawData.length) {
671
+ console.warn(`[TabularDriver] headerRow ${headerRow} exceeds data length ${rawData.length}, using 0`);
672
+ processedSheets++;
673
+ continue;
674
+ }
675
+
676
+ // Extract headers from the specified row (0-based index)
677
+ const headerRowData = rawData[headerRow] || [];
678
+ const headers = headerRowData.map((h: any, i: number) => {
679
+ if (h === null || h === undefined || String(h).trim() === '') {
680
+ return `__EMPTY${i > 0 ? '_' + i : ''}`;
681
+ }
682
+ return String(h).trim();
683
+ });
684
+
685
+ // Ensure we have at least one valid header
686
+ if (headers.length === 0 || headers.every((h: string) => h.startsWith('__EMPTY'))) {
687
+ console.warn(`[TabularDriver] No valid headers found at row ${headerRow}`);
688
+ processedSheets++;
689
+ continue;
690
+ }
691
+
692
+ // Build rows from data AFTER the header row
693
+ const rows: Record<string, any>[] = [];
694
+ for (let i = headerRow + 1; i < rawData.length; i++) {
695
+ const rowData = rawData[i];
696
+
697
+ // Skip completely empty rows
698
+ if (!rowData || rowData.length === 0) {
699
+ continue;
700
+ }
701
+
702
+ // Skip rows where all cells are null/undefined/empty
703
+ const hasContent = rowData.some((cell: any) =>
704
+ cell !== null && cell !== undefined && String(cell).trim() !== ''
705
+ );
706
+ if (!hasContent) {
707
+ continue;
708
+ }
709
+
710
+ const row: Record<string, any> = {};
711
+ headers.forEach((header: string, j: number) => {
712
+ row[header] = rowData[j] !== undefined ? rowData[j] : null;
713
+ });
714
+ rows.push(row);
715
+ }
716
+
717
+ if (rows.length > 0) {
718
+ sheets[sheetName] = new DataFrame(rows);
667
719
  }
668
720
 
669
721
  processedSheets++;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "juxscript",
3
- "version": "1.1.198",
3
+ "version": "1.1.200",
4
4
  "type": "module",
5
5
  "description": "A JavaScript UX authorship platform",
6
6
  "main": "index.js",