Ardis Lu [Fri, 4 Jul 2025 05:02:25 +0000 (22:02 -0700)]
Increase `highWaterMark` for `CSVWriter`'s queuing strategy
This change improves the 100MB Write benchmark from ~9s to ~7s.
Bumping `highWaterMark` to >1 also changes the stream's interaction with `AbortController`, so now the chunk processed during an abort is included in the write.
I believe this behavior has to do with the task queue order of the callback for the `AbortSignal`'s `abort` event - so now with multiple chunks in the queue, the last chunk is written before the `abort` event is processed. I was unable to force this writing code to occur after the `abort` event in a deterministic way.
This situation is a rare edge case so letting it through.
Ardis Lu [Fri, 4 Jul 2025 03:45:55 +0000 (20:45 -0700)]
Simplify and harden tick indicator
Relying on physical timing is flaky (e.g., it will fail if executing on a slow machine). Sending a simple `tick` increment into the task queue is more reliable.
Ardis Lu [Tue, 1 Jul 2025 04:19:16 +0000 (21:19 -0700)]
Increase default chunk size from 1 KiB to 64 KiB
Benchmarks showed improvements or no change across all tests. Notably, 100MB Read improved from ~13s to ~3s.
The magic value of 64 KiB was selected based on Node.js's default of 16 KiB in similar code [1] and manually testing some multiples over that (Node.js tends to be conservative).
Ardis Lu [Wed, 4 Jun 2025 06:45:32 +0000 (23:45 -0700)]
Simplify release notes to be auto generated
Reasons in favor of minimal release notes: (1) Releases is a GitHub functionality, it's better not to invest too much time into vendor-specific configurations. (2) There is no binary associated with this library so Releases has reduced significance. (3) Meaningful release notes are still contained in git tag annotations, which can be carried across hosts.
One downside is losing meaningful messages in email notifications if people subscribe to follow releases on GitHub.
Ardis Lu [Tue, 27 May 2025 05:01:57 +0000 (22:01 -0700)]
Refactor to pass options through to private fields
This change makes the code consistent with previous refactoring on the core code, and also prevents unexpected behavior from mutating the options object after instantiation.
Ardis Lu [Sun, 25 May 2025 04:55:24 +0000 (21:55 -0700)]
Explicitly import `ReadableStream` to make TS understand `ReadableStream.from`
This change does not affect the code execution, but it makes the TS language server understand the `ReadableStream.from` static function. Without the explicit import, it is not possible using only JSDoc to merge the `ReadableStream` instance interface with the `ReadableStream` constructor because they share the same name.
Ardis Lu [Sun, 25 May 2025 04:24:08 +0000 (21:24 -0700)]
Migrate from CLI options to explicit `tsconfig.json`
This change makes it easier to use an explicit `lib` configuration and types, which resolves type issues resulting from subtle mismatches between implied type imports (e.g., some files importing `ReadableStream` from TS's built-in Web API types and others importing from Node.js's `streams/web`).
This is the cleanest way to make a JS library importable to a TS project. This approach is similar to Svelte's approach.
Note the dev dependency on TS is only used for `.d.ts` generation. The source code itself still does not use TS (or any dependencies other than Node.js) at all.
Ardis Lu [Mon, 28 Apr 2025 06:07:57 +0000 (23:07 -0700)]
Block `cancel()` until `start()` is finished
If `cancel()` is called immediately after the stream is instantiated, it is possible that `start()` is not yet finished setting up the file handle before the `cancel()` logic is executed.
Ardis Lu [Sun, 27 Apr 2025 08:38:12 +0000 (01:38 -0700)]
Refactor to unpack `options` into private properties
This change makes these properties consistent with other classes in this library. This change is also the simplest way to let the TypeScript language server understand that these properties are not null.
Ardis Lu [Sun, 27 Apr 2025 08:30:01 +0000 (01:30 -0700)]
Refactor to simplify for language server
The TypeScript language server is not yet capable of understanding that the nullish coalescing assignment will make the property non-null, so it will show a type error. Another workaround would be to assert the property is non-null using a JSDoc equivalent to TypeScript's `!` but that is also not yet supported by JSDoc.
Ardis Lu [Fri, 4 Apr 2025 07:12:25 +0000 (00:12 -0700)]
Test UTF-16 BE decoding
`utf-16be` is not supported by Node.js's decoder in the `fs` module, but it is supported by the web standard Encoding API. So this is a good test to demonstrate the difference between the two.
Ardis Lu [Fri, 4 Apr 2025 06:51:45 +0000 (23:51 -0700)]
Remove dependency on Node.js `createReadStream`
This change decouples the file reading from the character decoding, which enables use of the web standard Encoding API (`TextDecoderStream`) instead of Node.js's internal decoder. The web standard allows a broader set of encodings.
Ardis Lu [Tue, 11 Feb 2025 06:41:02 +0000 (22:41 -0800)]
Assert non-nullable type instead of using nullish coalesce
There will be undefined `decimal` only if the input to `formatToParts` does not contain a decimal. But there will always be a decimal because the input is hardcoded.
The TS language server is not yet intelligent enough to assert it is non-nullable from the hardcoded input, so we need to pass the type hint.
Using nullish coalesce results in an uncovered branch which is impossible to test, so it should be removed.
Ardis Lu [Mon, 10 Feb 2025 04:21:02 +0000 (20:21 -0800)]
Delete unnecessary token
Originally intended to match the remaining characters of the rest of the test name, but this is not needed since we only need to match the "large:" prefix.
Ardis Lu [Sat, 8 Feb 2025 09:47:24 +0000 (01:47 -0800)]
Fix temp files not being deleted
The test runner will run code inside a test suite block even if the tests inside are skipped, which means the temp file was created but the cleanup `after()` call is skipped. Putting the creation within `before()` makes the temp file creation skipped it the tests are skipped.