# Literal table stack preview v1

Save `table-stack.mjs` beside a file named `table-stack-example.mjs` containing
the example below. Run `node table-stack-example.mjs` in Node 18+; the module also
works in modern JavaScript. No runtime dependencies.

```js
import assert from 'node:assert/strict';
import { previewTableStack } from './table-stack.mjs';
const result = previewTableStack(
  'id\tvalue\n001\t=formula()\n001\t=formula()',
  'id\tvalue\n002\t',
);
assert.equal(result.output, 'id\tvalue\n001\t=formula()\n001\t=formula()\n002\t');
assert.equal(result.firstRows, 2);
assert.equal(result.secondRows, 1);
assert.deepEqual(result.sourceRows, [{ table: 1, row: 2 }, { table: 1, row: 3 }, { table: 2, row: 2 }]);
const emptyLastRow = previewTableStack('value\nkeep', 'value\n\n');
assert.equal(emptyLastRow.output, 'value\nkeep\n\n');
assert.equal(emptyLastRow.secondRows, 1);
console.log(result.output);
```

Arguments: two literal TSV strings, each with a first-row header. Both are
required. Headers must match exactly, field by field and in the same order;
capitalization and surrounding spaces count. Blank and duplicate header names
are allowed. Every data row must have the same number of fields as its header.
Header-only tables are allowed.

The output includes the shared header once, followed by all first-table data
rows and then all second-table data rows. Duplicate rows, blank values, leading
zeros, quotes and formulas remain literal. Quotes do not escape tabs or newlines.
No header inference, column alignment, sorting, deduplication, aggregation,
formula evaluation or spreadsheet writes.

`output` is plain TSV; `lines` contains its logical rows without newline
terminators. Use `output` when copying the table so a final empty row is retained.
`firstRows` and `secondRows` count data rows, excluding
each input header. `inputColumns` and `outputColumns` give the shared column
count. `sourceRows` identifies each output data row by its table number and its
original 1-based row number, including the header in that numbering.

CRLF and bare CR become LF. Exactly one final newline is ignored in each input;
other blank rows are data. An empty one-column row at the end of the output has
an additional final newline terminator, so copying and re-reading the output
with the same rule preserves that row. For example, `value\n\n` contains a
header and one empty data row; `value\n` contains only the header. A blank
one-column header with no data rows is serialized as `\n` for the same reason.

Limits: 100,000 UTF-16 code units per input and for the output, 500 columns,
2,000 combined data rows (excluding the two input headers), and 10,000 output
cells (including the single output header). Empty/ragged inputs, unequal
headers or exceeded limits throw without partial output. No network or
telemetry. This does not certify spreadsheet import safety, time savings or
customer use.

Generate with `node scripts/build-table-stack.mjs`; verify browser-core bytes
with `node scripts/build-table-stack.mjs --check`.

## License

MIT License

Copyright (c) 2026 QuasiLife

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
