Skip to content

fix(csv-generate): preserve eof after an overflowing final record - #556

Open
asssslay wants to merge 1 commit into
adaltas:masterfrom
asssslay:fix/generate-preserve-eof
Open

asssslay wants to merge 1 commit into
adaltas:masterfrom
asssslay:fix/generate-preserve-eof

Conversation

@asssslay

@asssslay asssslay commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

csv-generate can drop its configured eof when the final text record crosses a stream read boundary. The same data produces the suffix at a larger read size, so generated files can inconsistently lose their trailing newline or custom terminator. The documented eof option promises trailing characters.

Reproduces on csv-generate 4.6.2 and the parent revision:

import { generate } from "csv-generate/sync";

generate({
  columns: [() => "xx"],
  length: 1,
  highWaterMark: 1,
  eof: "END",
});
// Before: "xx"
// After:  "xxEND"

The overflowing record is emitted immediately. On the next read, finalization sees an empty data buffer and closes without emitting EOF. Treat the pending text-mode EOF as output to flush, even when no record text remains. The existing end-state guard prevents duplicate suffixes; empty output and object-mode records retain their current behavior. After an overflow, the suffix can be emitted as a separate final chunk.

Four new regressions fail before the fix and pass afterward, covering callback, sync, async iteration and Web Stream APIs. The tests also cover custom row delimiters, delayed output, fixed-size boundaries, exactly-once emission, empty output and object mode.

Related to #555, which fixes fixed-size remainder consumption. This also reproduces with the default fixed_size: false after that change. Generated distributions were rebuilt and checked, and are left to the release build process.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant