juxscript 1.1.199 → 1.1.201

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,7 +487,8 @@ 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
494
  const { maxSheetSize = 100000, sheetChunkSize = 10000, onProgress, headerRow = 0 } = options;
@@ -520,58 +521,78 @@ export class TabularDriver {
520
521
  }
521
522
  const range = XLSX.utils.decode_range(ref);
522
523
  const totalRows = range.e.r - range.s.r + 1;
524
+ const totalCols = range.e.c - range.s.c + 1;
523
525
  if (totalRows === 0) {
524
526
  processedSheets++;
525
527
  continue;
526
528
  }
527
- // FIX: Use sheet_to_json with header option to get raw arrays first
528
- // Then manually construct the DataFrame with the correct header row
529
- if (headerRow > 0) {
530
- // Get all data as raw arrays (no header interpretation)
531
- const rawData = XLSX.utils.sheet_to_json(worksheet, {
532
- header: 1, // Return array of arrays
533
- defval: null,
534
- raw: false,
535
- blankrows: false
536
- });
537
- if (rawData.length <= headerRow) {
538
- processedSheets++;
539
- continue;
529
+ // Get all data as raw arrays (header: 1 returns array of arrays)
530
+ const rawData = XLSX.utils.sheet_to_json(worksheet, {
531
+ header: 1,
532
+ defval: null,
533
+ raw: false,
534
+ blankrows: true
535
+ });
536
+ if (rawData.length === 0) {
537
+ processedSheets++;
538
+ continue;
539
+ }
540
+ // Validate headerRow is within bounds
541
+ if (headerRow >= rawData.length) {
542
+ console.warn(`[TabularDriver] headerRow ${headerRow} exceeds data length ${rawData.length}`);
543
+ processedSheets++;
544
+ continue;
545
+ }
546
+ // Get the header row data - ensure we have all columns
547
+ const headerRowData = rawData[headerRow] || [];
548
+ // Determine the maximum number of columns across all rows
549
+ let maxCols = totalCols;
550
+ for (let i = headerRow; i < Math.min(rawData.length, headerRow + 100); i++) {
551
+ if (rawData[i] && rawData[i].length > maxCols) {
552
+ maxCols = rawData[i].length;
540
553
  }
541
- // Extract headers from the specified row
542
- const headers = rawData[headerRow].map((h, i) => {
543
- if (h === null || h === undefined || String(h).trim() === '') {
544
- return `__EMPTY${i > 0 ? '_' + i : ''}`;
545
- }
546
- return String(h);
547
- });
548
- // Build rows from data after header row
549
- const rows = [];
550
- for (let i = headerRow + 1; i < rawData.length; i++) {
551
- const rowData = rawData[i];
552
- if (!rowData || rowData.every((cell) => cell === null || cell === undefined)) {
553
- continue; // Skip empty rows
554
- }
555
- const row = {};
556
- headers.forEach((header, j) => {
557
- row[header] = rowData[j] !== undefined ? rowData[j] : null;
558
- });
559
- rows.push(row);
554
+ }
555
+ // Build headers array with proper length
556
+ const headers = [];
557
+ for (let j = 0; j < maxCols; j++) {
558
+ const h = headerRowData[j];
559
+ if (h === null || h === undefined || String(h).trim() === '') {
560
+ headers.push(`__EMPTY${j > 0 ? '_' + j : ''}`);
560
561
  }
561
- if (rows.length > 0) {
562
- sheets[sheetName] = new DataFrame(rows);
562
+ else {
563
+ headers.push(String(h).trim());
563
564
  }
564
565
  }
565
- else {
566
- // Default behavior: first row is header
567
- const jsonData = XLSX.utils.sheet_to_json(worksheet, {
568
- defval: null,
569
- raw: false,
570
- blankrows: false
571
- });
572
- if (jsonData.length > 0) {
573
- sheets[sheetName] = new DataFrame(jsonData);
566
+ // Ensure we have at least one valid header
567
+ const validHeaders = headers.filter(h => !h.startsWith('__EMPTY'));
568
+ if (validHeaders.length === 0) {
569
+ console.warn(`[TabularDriver] No valid headers found at row ${headerRow}`);
570
+ processedSheets++;
571
+ continue;
572
+ }
573
+ // Build rows from data AFTER the header row
574
+ const rows = [];
575
+ for (let i = headerRow + 1; i < rawData.length; i++) {
576
+ const rowData = rawData[i];
577
+ // Skip completely empty rows
578
+ if (!rowData || rowData.length === 0) {
579
+ continue;
574
580
  }
581
+ // Skip rows where all cells are null/undefined/empty
582
+ const hasContent = rowData.some((cell) => cell !== null && cell !== undefined && String(cell).trim() !== '');
583
+ if (!hasContent) {
584
+ continue;
585
+ }
586
+ const row = {};
587
+ for (let j = 0; j < headers.length; j++) {
588
+ const header = headers[j];
589
+ const cellValue = j < rowData.length ? rowData[j] : null;
590
+ row[header] = cellValue;
591
+ }
592
+ rows.push(row);
593
+ }
594
+ if (rows.length > 0) {
595
+ sheets[sheetName] = new DataFrame(rows);
575
596
  }
576
597
  processedSheets++;
577
598
  if (onProgress) {
@@ -607,7 +607,8 @@ 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
614
  const { maxSheetSize = 100000, sheetChunkSize = 10000, onProgress, headerRow = 0 } = options;
@@ -646,65 +647,92 @@ export class TabularDriver {
646
647
 
647
648
  const range = XLSX.utils.decode_range(ref);
648
649
  const totalRows = range.e.r - range.s.r + 1;
650
+ const totalCols = range.e.c - range.s.c + 1;
649
651
 
650
652
  if (totalRows === 0) {
651
653
  processedSheets++;
652
654
  continue;
653
655
  }
654
656
 
655
- // FIX: Use sheet_to_json with header option to get raw arrays first
656
- // Then manually construct the DataFrame with the correct header row
657
- if (headerRow > 0) {
658
- // Get all data as raw arrays (no header interpretation)
659
- const rawData: any[][] = XLSX.utils.sheet_to_json(worksheet, {
660
- header: 1, // Return array of arrays
661
- defval: null,
662
- raw: false,
663
- blankrows: false
664
- });
657
+ // Get all data as raw arrays (header: 1 returns array of arrays)
658
+ const rawData: any[][] = XLSX.utils.sheet_to_json(worksheet, {
659
+ header: 1,
660
+ defval: null,
661
+ raw: false,
662
+ blankrows: true
663
+ });
665
664
 
666
- if (rawData.length <= headerRow) {
667
- processedSheets++;
668
- continue;
665
+ if (rawData.length === 0) {
666
+ processedSheets++;
667
+ continue;
668
+ }
669
+
670
+ // Validate headerRow is within bounds
671
+ if (headerRow >= rawData.length) {
672
+ console.warn(`[TabularDriver] headerRow ${headerRow} exceeds data length ${rawData.length}`);
673
+ processedSheets++;
674
+ continue;
675
+ }
676
+
677
+ // Get the header row data - ensure we have all columns
678
+ const headerRowData = rawData[headerRow] || [];
679
+
680
+ // Determine the maximum number of columns across all rows
681
+ let maxCols = totalCols;
682
+ for (let i = headerRow; i < Math.min(rawData.length, headerRow + 100); i++) {
683
+ if (rawData[i] && rawData[i].length > maxCols) {
684
+ maxCols = rawData[i].length;
669
685
  }
686
+ }
670
687
 
671
- // Extract headers from the specified row
672
- const headers = rawData[headerRow].map((h: any, i: number) => {
673
- if (h === null || h === undefined || String(h).trim() === '') {
674
- return `__EMPTY${i > 0 ? '_' + i : ''}`;
675
- }
676
- return String(h);
677
- });
688
+ // Build headers array with proper length
689
+ const headers: string[] = [];
690
+ for (let j = 0; j < maxCols; j++) {
691
+ const h = headerRowData[j];
692
+ if (h === null || h === undefined || String(h).trim() === '') {
693
+ headers.push(`__EMPTY${j > 0 ? '_' + j : ''}`);
694
+ } else {
695
+ headers.push(String(h).trim());
696
+ }
697
+ }
678
698
 
679
- // Build rows from data after header row
680
- const rows: Record<string, any>[] = [];
681
- for (let i = headerRow + 1; i < rawData.length; i++) {
682
- const rowData = rawData[i];
683
- if (!rowData || rowData.every((cell: any) => cell === null || cell === undefined)) {
684
- continue; // Skip empty rows
685
- }
699
+ // Ensure we have at least one valid header
700
+ const validHeaders = headers.filter(h => !h.startsWith('__EMPTY'));
701
+ if (validHeaders.length === 0) {
702
+ console.warn(`[TabularDriver] No valid headers found at row ${headerRow}`);
703
+ processedSheets++;
704
+ continue;
705
+ }
686
706
 
687
- const row: Record<string, any> = {};
688
- headers.forEach((header: string, j: number) => {
689
- row[header] = rowData[j] !== undefined ? rowData[j] : null;
690
- });
691
- rows.push(row);
707
+ // Build rows from data AFTER the header row
708
+ const rows: Record<string, any>[] = [];
709
+ for (let i = headerRow + 1; i < rawData.length; i++) {
710
+ const rowData = rawData[i];
711
+
712
+ // Skip completely empty rows
713
+ if (!rowData || rowData.length === 0) {
714
+ continue;
692
715
  }
693
716
 
694
- if (rows.length > 0) {
695
- sheets[sheetName] = new DataFrame(rows);
717
+ // Skip rows where all cells are null/undefined/empty
718
+ const hasContent = rowData.some((cell: any) =>
719
+ cell !== null && cell !== undefined && String(cell).trim() !== ''
720
+ );
721
+ if (!hasContent) {
722
+ continue;
696
723
  }
697
- } else {
698
- // Default behavior: first row is header
699
- const jsonData: Record<string, any>[] = XLSX.utils.sheet_to_json(worksheet, {
700
- defval: null,
701
- raw: false,
702
- blankrows: false
703
- });
704
724
 
705
- if (jsonData.length > 0) {
706
- sheets[sheetName] = new DataFrame(jsonData);
725
+ const row: Record<string, any> = {};
726
+ for (let j = 0; j < headers.length; j++) {
727
+ const header = headers[j];
728
+ const cellValue = j < rowData.length ? rowData[j] : null;
729
+ row[header] = cellValue;
707
730
  }
731
+ rows.push(row);
732
+ }
733
+
734
+ if (rows.length > 0) {
735
+ sheets[sheetName] = new DataFrame(rows);
708
736
  }
709
737
 
710
738
  processedSheets++;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "juxscript",
3
- "version": "1.1.199",
3
+ "version": "1.1.201",
4
4
  "type": "module",
5
5
  "description": "A JavaScript UX authorship platform",
6
6
  "main": "index.js",