@justybase/spreadsheet-tasks 2.2.0 → 3.0.0

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/docs/API.md CHANGED
@@ -62,7 +62,10 @@ Writes data to the current sheet.
62
62
  - `string` - Written as shared string
63
63
  - `number` - Written as number (integer or double)
64
64
  - `boolean` - Written as boolean
65
- - `Date` - Written as Excel date serial number
65
+ - `Date` - Written as Excel date serial number. The serial is taken from the UTC
66
+ time (`getTime()`), not local wall-clock time: `new Date(2024, 5, 30)` in UTC+2
67
+ is stored as 2024-06-29 22:00 and shows that way in Excel. Use `Date.UTC(...)`
68
+ for date-only values
66
69
  - `null` / `undefined` - Written as empty cell
67
70
 
68
71
  **Example:**
@@ -161,6 +164,12 @@ console.log(sheets); // ['Sheet1', 'Sheet2']
161
164
  Reads the next row. Returns `true` if a row was read, `false` if end of sheet reached.
162
165
  Always use `await` (both XLSB and XLSX are async in v2+).
163
166
 
167
+ Empty rows: gaps in the sheet (missing `<row>` / `BrtRowHdr`, including leading
168
+ gaps) are returned as empty rows (`[]`, `getValue()` → `null`). Like xlspy,
169
+ gap positions are yielded; unlike xlspy's padded `[None] * cols`, this reader
170
+ yields a zero-length row so callers must not assume `fieldCount` width.
171
+ The 1904 date system (`workbookPr date1904` / `BrtWbProp`) is honoured.
172
+
164
173
  **Example:**
165
174
  ```typescript
166
175
  while (await reader.read()) {
@@ -168,6 +177,27 @@ while (await reader.read()) {
168
177
  }
169
178
  ```
170
179
 
180
+ #### `selectSheet(nameOrIndex: string | number): Promise<void>`
181
+
182
+ Selects a worksheet for subsequent `read()` calls. Resets row/EOF and `fieldCount`.
183
+ Default is sheet 0.
184
+
185
+ ```typescript
186
+ await reader.selectSheet('Second');
187
+ await reader.selectSheet(0);
188
+ ```
189
+
190
+ #### `nextResult(): Promise<boolean>`
191
+
192
+ Advances to the next worksheet. Returns `true` if another sheet was selected,
193
+ `false` at the end.
194
+
195
+ ```typescript
196
+ do {
197
+ while (await reader.read()) { /* rows */ }
198
+ } while (await reader.nextResult());
199
+ ```
200
+
171
201
  #### `getValue(columnIndex: number): CellValue`
172
202
 
173
203
  Gets value at the specified column index in the current row.
@@ -177,6 +207,9 @@ Gets value at the specified column index in the current row.
177
207
 
178
208
  **Returns:** `CellValue` (string, number, boolean, Date, bigint, or null/undefined)
179
209
 
210
+ Date cells are returned as `Date` objects built from the serial in UTC, the same
211
+ convention the writers use, so a write/read round trip keeps the same instant.
212
+
180
213
  **Example:**
181
214
  ```typescript
182
215
  while (await reader.read()) {
@@ -221,6 +254,16 @@ Returns array of worksheet names.
221
254
  #### `read(): Promise<boolean>`
222
255
 
223
256
  Reads the next row. Returns `true` if a row was read. Always use `await`.
257
+ Empty gap rows (including leading) are returned as empty rows; see
258
+ [XlsbReader](#xlsbreader) for `selectSheet`/`nextResult`, which behave identically.
259
+
260
+ #### `selectSheet(nameOrIndex: string | number): Promise<void>`
261
+
262
+ See [XlsbReader](#xlsbreader).
263
+
264
+ #### `nextResult(): Promise<boolean>`
265
+
266
+ See [XlsbReader](#xlsbreader).
224
267
 
225
268
  #### `getValue(columnIndex: number): CellValue`
226
269
 
@@ -288,6 +331,12 @@ Clears the entire cell data of the target sheet and writes new rows in its place
288
331
  - Pivot tables whose `worksheetSource` references the updated sheet get their
289
332
  `ref` and `recordCount` adjusted, and `refreshOnLoad="1"` is added to the
290
333
  pivot table definitions so Excel refreshes them on open.
334
+ - The stale calculation chain (`xl/calcChain.xml`) is removed with its
335
+ `Content_Types`/rels entries; Excel rebuilds it on open.
336
+ - ListObject tables (`xl/tables/*.xml`) anchored at `A1` get their `<table>`
337
+ and `<autoFilter>` `ref` updated to the new dimension. Tables whose column
338
+ count changes are left untouched (their `tableColumns` would need rebuilding),
339
+ and ranges are capped so they never overlap another table.
291
340
 
292
341
  **Example:**
293
342
  ```typescript
@@ -384,6 +433,10 @@ Clears the entire cell data of the target sheet and writes new rows in its place
384
433
  - Pivot caches whose `worksheetSource` references the updated sheet get their
385
434
  range and record count adjusted, and the `refreshOnLoad` flag is set so Excel
386
435
  refreshes them on open.
436
+ - The stale calculation chain (`xl/calcChain.bin`) is removed with its
437
+ `Content_Types`/rels entries.
438
+ - XLSB ListObject tables are **not** patched (documented limitation); only the
439
+ sheet dimension (`BrtWsDim`) and pivot caches are updated.
387
440
 
388
441
  **Example:**
389
442
  ```typescript
@@ -478,6 +531,18 @@ await reader.open('data.xlsb');
478
531
 
479
532
  ## Types
480
533
 
534
+ ### Excel limits (throw, xlspy parity)
535
+
536
+ ```typescript
537
+ import { MAX_ROWS, MAX_COLS, MAX_CELL_CHARS } from '@justybase/spreadsheet-tasks';
538
+ // MAX_ROWS = 1_048_576, MAX_COLS = 16_384, MAX_CELL_CHARS = 32_767 UTF-16 units
539
+ ```
540
+
541
+ Writers throw when a limit is exceeded (no truncation, workbook not published).
542
+ `writeSheet` also throws when a row/header is longer than `columnCount`, matching
543
+ streaming `writeRow` behaviour. Astral characters count as 2 units
544
+ (`'😀'.length === 2`).
545
+
481
546
  ### Supported Cell Types
482
547
 
483
548
  | TypeScript Type | Excel Cell Type |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@justybase/spreadsheet-tasks",
3
- "version": "2.2.0",
3
+ "version": "3.0.0",
4
4
  "description": "High-performance TypeScript library for reading and writing Excel files in XLSB and XLSX formats. XLSB is 3.3x faster to write and 2.3x faster to read than XLSX.",
5
5
  "main": "./dist/cjs/index.js",
6
6
  "module": "./dist/esm/index.js",
@@ -26,10 +26,10 @@
26
26
  "build": "tsup && node -e \"require('fs').copyFileSync('dist-esm-package.json','dist/esm/package.json')\"",
27
27
  "build:browser": "esbuild src/browser/download.ts --bundle --minify --format=iife --global-name=JustybaseSpreadsheet --outfile=browser/justybase-spreadsheet.min.js && esbuild src/browser/download.ts --bundle --format=esm --outfile=browser/browser-spreadsheet.js",
28
28
  "lint": "eslint src/",
29
- "typecheck": "tsc --noEmit",
29
+ "typecheck": "tsc --noEmit && tsc -p tsconfig.browser.json",
30
30
  "test": "npm run typecheck && npm run test:smoke && npm run test:unit && npm run test:integration && npm run test:dist",
31
31
  "test:smoke": "npx ts-node tests/smoke.test.ts",
32
- "test:unit": "npx ts-node tests/unit/bigbuffer.test.ts && npx ts-node tests/unit/biff-reader-writer.test.ts && npx ts-node tests/unit/xlsb-writer.test.ts && npx ts-node tests/unit/excel-converter.test.ts && npx ts-node tests/unit/updater-streaming.test.ts",
32
+ "test:unit": "npx ts-node tests/unit/bigbuffer.test.ts && npx ts-node tests/unit/biff-reader-writer.test.ts && npx ts-node tests/unit/xlsb-writer.test.ts && npx ts-node tests/unit/excel-converter.test.ts && npx ts-node tests/unit/updater-streaming.test.ts && npx ts-node tests/unit/xlsx-reader-cell-refs.test.ts && npx ts-node tests/unit/writer-limits-columns.test.ts && npx ts-node tests/unit/reader-xml-fixes.test.ts && npx ts-node tests/unit/xlsb-sst-dim.test.ts && npx ts-node tests/unit/updater-cleanup.test.ts && npx ts-node tests/unit/oa-1900-leap.test.ts && npx ts-node tests/unit/reader-row-limit.test.ts",
33
33
  "test:integration": "npx ts-node tests/integration/xlsb-writer.test.ts && npx ts-node tests/integration/xlsx-writer.test.ts && npx ts-node tests/integration/xlsx-updater.test.ts && npx ts-node tests/integration/xlsb-updater.test.ts",
34
34
  "test:dist": "npm run build && npx ts-node tests/dist-surface.test.ts",
35
35
  "test:excel-conversion": "npm run build && npx ts-node tests/excel-compat/conversion.ts",
@@ -38,6 +38,7 @@
38
38
  "benchmark": "npm run build && npx ts-node benchmarks/performance.bench.ts",
39
39
  "benchmark:comparison": "npm run build && npx ts-node benchmarks/comparison.bench.ts",
40
40
  "test:excel-compat": "npm run build && npx tsx tests/excel-compat/run.ts",
41
+ "test:cross": "npx ts-node tests/cross/xlspy-cross.test.ts",
41
42
  "prepublishOnly": "npm run build && npm run build:browser && npm test"
42
43
  },
43
44
  "keywords": [