perf(core): optimize async operation & progress events #23
perf(core): optimize async operation & progress events #23
Conversation
- Global CLI, you do not need to wrap active downloads with downloadSequence - Auto increase parallel stream, maximize download speed - Not reusing redirected URL by default - prevent token expires for long downloads - Performance & stability improvements - Remote CLI progress, show download progress in another process easily BREAKING CHANGE: - `partsURL` removed in favor of `partURLs` - Not reusing redirected URL by default - Different chunk size based on programType - You can recall `.download()` and it will not throw an error - will return the same promise of downloading (do *not* redownload the file) - You can change the parallel stream count after download has started
# Conflicts: # package-lock.json # package.json # src/download/download-engine/download-file/download-engine-file.ts # src/download/download-engine/download-file/progress-status-file.ts # src/download/download-engine/engine/download-engine-multi-download.ts # src/download/download-engine/engine/download-engine-nodejs.ts # src/download/download-engine/streams/download-engine-fetch-stream/base-download-engine-fetch-stream.ts # src/download/download-engine/streams/download-engine-fetch-stream/download-engine-fetch-stream-fetch.ts # src/download/download-engine/streams/download-engine-fetch-stream/download-engine-fetch-stream-xhr.ts # src/download/download-engine/streams/download-engine-write-stream/download-engine-write-stream-nodejs.ts # src/download/transfer-visualize/progress-statistics-builder.ts # src/download/transfer-visualize/transfer-cli/GlobalCLI.ts # src/download/transfer-visualize/transfer-cli/multiProgressBars/BaseMultiProgressBar.ts # src/download/transfer-visualize/transfer-cli/transfer-cli.ts # test/browser.test.ts # test/download.test.ts # test/fetchDownloadInfo.test.ts
There was a problem hiding this comment.
Pull request overview
This PR focuses on performance and dependency reduction in the download progress/CLI visualization and Node.js write path, while updating CI/build config and tests to match the new behavior.
Changes:
- Replaced
pretty-bytes/pretty-mswith new in-repo “fast” formatters and updated CLI/progress rendering to use them. - Reworked parts of the download engine runtime behavior (write buffering via
WriteQueue, progress throttling, metadata-save hook changes, CLI update debouncing/caching). - Updated test setup (timeouts, fixtures) and CI build pipeline (new
tsconfig.prod.json,build:prod, Vitest upgrade).
Reviewed changes
Copilot reviewed 31 out of 32 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
vitest.config.ts |
Switches to a global test timeout instead of forcing single-thread workers. |
tsconfig.prod.json |
Adds a production TypeScript build config (used by CI). |
test/utils/files.ts |
Updates large-file test fixture URL. |
test/utils/download.ts |
Adjusts local test fixture path/metadata fields. |
test/fetchDownloadInfo.test.ts |
Updates header string and snapshot formatting; removes per-suite timeout override. |
test/download.test.ts |
Tweaks chunk size and removes per-suite timeout override. |
test/copy-file.test.ts |
Removes per-suite timeout override. |
test/browser.test.ts |
Updates expected hashes; changes concurrency options; skips one browser-memory test. |
src/download/transfer-visualize/utils/prettyMSFast.ts |
Adds fast compact duration formatting. |
src/download/transfer-visualize/utils/prettyBytesFast.ts |
Adds fast byte formatting with optional locale/format controls. |
src/download/transfer-visualize/transfer-statistics.ts |
Avoids divide-by-zero when total bytes is 0. |
src/download/transfer-visualize/transfer-cli/transfer-cli.ts |
Replaces lodash debounce with manual time-based throttling + SIGINT behavior changes. |
src/download/transfer-visualize/transfer-cli/progress-bars/fancy-transfer-cli-progress-bar.ts |
Switches duration formatting to the new formatter. |
src/download/transfer-visualize/transfer-cli/multiProgressBars/BaseMultiProgressBar.ts |
Switches byte formatting to the new formatter. |
src/download/transfer-visualize/transfer-cli/GlobalCLI.ts |
Adds caching/invalidation for displayed engines; adapts to new updateStatues() API. |
src/download/transfer-visualize/progress-statistics-builder.ts |
Adds common transfer-action aggregation + cached loading status. |
src/download/transfer-visualize/format-transfer-status.ts |
Switches formatting helpers to new fast formatters. |
src/download/download-engine/streams/download-engine-write-stream/utils/WriteQueue.ts |
Introduces buffered coalescing queue for positional writes. |
src/download/download-engine/streams/download-engine-write-stream/download-engine-write-stream-nodejs.ts |
Integrates WriteQueue, changes metadata flush behavior, adds finalizer-based fd cleanup. |
src/download/download-engine/streams/download-engine-fetch-stream/download-engine-fetch-stream-xhr.ts |
Cleans abort listener management; switches timeout formatting; adjusts length detection. |
src/download/download-engine/streams/download-engine-fetch-stream/download-engine-fetch-stream-fetch.ts |
Cleans abort listener lifecycle; switches timeout formatting; adjusts length detection. |
src/download/download-engine/streams/download-engine-fetch-stream/base-download-engine-fetch-stream.ts |
Adds cloned-listener cleanup to prevent leaks. |
src/download/download-engine/engine/download-engine-nodejs.ts |
Adapts save-progress hook to new write-stream metadata API. |
src/download/download-engine/engine/download-engine-multi-download.ts |
Ensures close() happens on error path too. |
src/download/download-engine/download-file/progress-status-file.ts |
Replaces ProgressStatusFile class usage with EMPTY_PROGRESS_STATUS constant. |
src/download/download-engine/download-file/download-engine-file.ts |
Reworks progress status creation, adds progress throttling, changes save-progress hook shape. |
src/cli/cli.ts |
Adjusts save-path interpretation and output naming behavior. |
README.md |
Improves browser usage docs around CORS/range + manual download info. |
package.json |
Adds build:prod, upgrades dependencies (Vitest, xmlhttprequest-ssl, semantic-release), removes pretty-* deps. |
.github/workflows/test.yml |
Uses build:prod in CI. |
.github/workflows/build.yml |
Uses build:prod in CI; updates release job environment usage. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
...d/download-engine/streams/download-engine-fetch-stream/download-engine-fetch-stream-fetch.ts
Outdated
Show resolved
Hide resolved
...oad/download-engine/streams/download-engine-fetch-stream/download-engine-fetch-stream-xhr.ts
Outdated
Show resolved
Hide resolved
src/download/download-engine/streams/download-engine-write-stream/utils/WriteQueue.ts
Outdated
Show resolved
Hide resolved
.../download-engine/streams/download-engine-write-stream/download-engine-write-stream-nodejs.ts
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Pull request overview
This PR modernizes the project’s build/test tooling and refactors download progress/reporting internals for performance and reliability, including replacing third-party “pretty” formatters with internal fast implementations and introducing a new buffered write queue for Node.js writes.
Changes:
- Upgrade tooling (Vitest v4, new
tsconfig.prod.json, CI usesbuild:prod, update test timeouts). - Replace
pretty-bytes/pretty-mswith new internalprettyBytesFast/prettyMSFastand update CLI progress formatting. - Refactor Node.js write stream to use a new
WriteQueueand adjust progress saving / CLI update behavior.
Reviewed changes
Copilot reviewed 31 out of 32 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| vitest.config.ts | Removes worker pinning and sets a global test timeout. |
| tsconfig.prod.json | Adds a production TS build config used by CI. |
| test/utils/files.ts | Changes the “big file” test fixture URL. |
| test/utils/download.ts | Updates big-file filename and augments test download info payload. |
| test/fetchDownloadInfo.test.ts | Adjusts headers formatting and relies on global timeouts. |
| test/download.test.ts | Updates chunk size and relies on global timeouts. |
| test/copy-file.test.ts | Relies on global timeouts. |
| test/browser.test.ts | Updates snapshots, concurrency options, and skips XHR memory test. |
| src/download/transfer-visualize/utils/prettyMSFast.ts | Adds a compact millisecond formatter. |
| src/download/transfer-visualize/utils/prettyBytesFast.ts | Adds a fast pretty-bytes replacement (+ trunc formatter). |
| src/download/transfer-visualize/transfer-statistics.ts | Fixes divide-by-zero percentage when total is 0. |
| src/download/transfer-visualize/transfer-cli/transfer-cli.ts | Replaces lodash debounce with a manual debounce + progress getter. |
| src/download/transfer-visualize/transfer-cli/progress-bars/fancy-transfer-cli-progress-bar.ts | Switches to internal pretty-ms formatter. |
| src/download/transfer-visualize/transfer-cli/multiProgressBars/BaseMultiProgressBar.ts | Switches to internal pretty-bytes formatter. |
| src/download/transfer-visualize/transfer-cli/GlobalCLI.ts | Adds CLI engine/status caching and integrates new TransferCli API. |
| src/download/transfer-visualize/progress-statistics-builder.ts | Improves aggregated status and uses shared empty progress status. |
| src/download/transfer-visualize/format-transfer-status.ts | Switches to internal formatters; changes percentage formatting logic. |
| src/download/download-engine/streams/download-engine-write-stream/utils/WriteQueue.ts | Introduces a coalescing buffered writer with parallel positional writes. |
| src/download/download-engine/streams/download-engine-write-stream/download-engine-write-stream-nodejs.ts | Refactors Node write stream to use WriteQueue + deferred metadata flush. |
| src/download/download-engine/streams/download-engine-fetch-stream/download-engine-fetch-stream-xhr.ts | Improves timeout message formatting and content-length handling. |
| src/download/download-engine/streams/download-engine-fetch-stream/download-engine-fetch-stream-fetch.ts | Cleans abort listener lifecycle; improves content-length logic; updates timeout msg formatting. |
| src/download/download-engine/streams/download-engine-fetch-stream/base-download-engine-fetch-stream.ts | Adds cleanup for cloned-state listeners to prevent leaks. |
| src/download/download-engine/engine/download-engine-nodejs.ts | Updates progress-save hook to the new sync onSaveProgress flow. |
| src/download/download-engine/engine/download-engine-multi-download.ts | Ensures close occurs on error and tweaks finish sequence. |
| src/download/download-engine/download-file/progress-status-file.ts | Replaces ProgressStatusFile class with EMPTY_PROGRESS_STATUS. |
| src/download/download-engine/download-file/download-engine-file.ts | Refactors status construction, throttles progress events, changes save callback API. |
| src/cli/cli.ts | Reworks --save path handling and file naming behavior. |
| README.md | Clarifies CORS/range-request workaround usage and documents manual download info. |
| package.json | Adds build:prod, upgrades vitest/xmlhttprequest-ssl/semantic-release, removes pretty-* deps. |
| .github/workflows/test.yml | Runs build:prod in CI instead of build. |
| .github/workflows/build.yml | Runs build:prod and adjusts release env vars. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/download/download-engine/streams/download-engine-write-stream/utils/WriteQueue.ts
Outdated
Show resolved
Hide resolved
.../download-engine/streams/download-engine-write-stream/download-engine-write-stream-nodejs.ts
Show resolved
Hide resolved
.../download-engine/streams/download-engine-write-stream/download-engine-write-stream-nodejs.ts
Show resolved
Hide resolved
There was a problem hiding this comment.
Pull request overview
This PR focuses on improving download/CLI performance and reliability by replacing some third-party formatting utilities with faster local implementations, introducing a new buffered write queue for Node.js writes, and updating CI/test configuration to match the new build/test behavior.
Changes:
- Added high-performance
prettyBytes/prettyMSutilities and wired them into transfer/CLI rendering. - Introduced a new
WriteQueueand refactored the Node.js write stream + progress saving behavior. - Updated CI to use a new
build:prod(viatsconfig.prod.json) and refreshed tests/configs for timeouts and fixtures.
Reviewed changes
Copilot reviewed 31 out of 32 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| vitest.config.ts | Removes single-worker constraints; sets a global test timeout. |
| tsconfig.prod.json | Adds a production TS build config (no sourcemaps, emit to dist). |
| test/utils/files.ts | Switches BIG_FILE fixture URL to a different large remote file. |
| test/utils/download.ts | Updates big-file example extension and download metadata fields. |
| test/fetchDownloadInfo.test.ts | Adjusts headers/snapshots and removes suite timeout override. |
| test/download.test.ts | Tweaks chunk size and removes suite timeout override. |
| test/copy-file.test.ts | Removes suite timeout override. |
| test/browser.test.ts | Updates snapshots, changes concurrency/repeats usage, and skips an xhr memory test. |
| src/download/transfer-visualize/utils/prettyMSFast.ts | Adds fast compact milliseconds formatter. |
| src/download/transfer-visualize/utils/prettyBytesFast.ts | Adds fast pretty-bytes implementation (number+bigint + options). |
| src/download/transfer-visualize/transfer-statistics.ts | Fixes percentage calculation when total is zero. |
| src/download/transfer-visualize/transfer-cli/transfer-cli.ts | Reworks CLI update throttling/debouncing and SIGINT behavior. |
| src/download/transfer-visualize/transfer-cli/progress-bars/fancy-transfer-cli-progress-bar.ts | Switches to internal prettyMS formatter. |
| src/download/transfer-visualize/transfer-cli/multiProgressBars/BaseMultiProgressBar.ts | Switches to internal prettyBytes formatter. |
| src/download/transfer-visualize/transfer-cli/GlobalCLI.ts | Adds caching + update getter approach for CLI status collection. |
| src/download/transfer-visualize/progress-statistics-builder.ts | Improves multi-engine aggregation and caches loading status formatting. |
| src/download/transfer-visualize/format-transfer-status.ts | Switches formatting to internal prettyBytes/prettyMS + trunc formatting. |
| src/download/download-engine/streams/download-engine-write-stream/utils/WriteQueue.ts | Introduces a new coalescing/parallel positional write buffer. |
| src/download/download-engine/streams/download-engine-write-stream/download-engine-write-stream-nodejs.ts | Refactors Node.js write stream to use WriteQueue + deferred metadata flush. |
| src/download/download-engine/streams/download-engine-fetch-stream/download-engine-fetch-stream-xhr.ts | Cleans up abort handlers and improves length detection with encoding/range logic. |
| src/download/download-engine/streams/download-engine-fetch-stream/download-engine-fetch-stream-fetch.ts | Ensures abort listener cleanup and improves length detection with encoding/range logic. |
| src/download/download-engine/streams/download-engine-fetch-stream/base-download-engine-fetch-stream.ts | Adds cloned-state listener cleanup to avoid leaks across retries/clones. |
| src/download/download-engine/engine/download-engine-nodejs.ts | Updates progress-saving hook to the new write-stream metadata flush API. |
| src/download/download-engine/engine/download-engine-multi-download.ts | Ensures close is called on failure and tweaks completion flow. |
| src/download/download-engine/download-file/progress-status-file.ts | Replaces ProgressStatusFile class with a shared EMPTY_PROGRESS_STATUS constant. |
| src/download/download-engine/download-file/download-engine-file.ts | Refactors status building, throttles progress events, and changes save callback shape. |
| src/cli/cli.ts | Improves --save path handling for directory vs file and multi-file naming. |
| README.md | Clarifies CORS/range options and documents manual download info override. |
| package.json | Adds build:prod, updates tool versions, removes pretty-* deps, upgrades vitest/xmlhttprequest-ssl. |
| .github/workflows/test.yml | Uses build:prod in CI typecheck step. |
| .github/workflows/build.yml | Uses build:prod and updates release env setup. |
Comments suppressed due to low confidence (1)
src/download/transfer-visualize/transfer-cli/transfer-cli.ts:5
lodash.debouncewas removed from this file, and a repo-wide search shows no remaining usages. Consider removing thelodash.debouncedependency from package.json as well to avoid shipping/maintaining an unused dependency.
import UpdateManager from "stdout-update";
import {TransferCliProgressBar} from "./progress-bars/base-transfer-cli-progress-bar.js";
import cliSpinners from "cli-spinners";
import {FormattedStatus} from "../format-transfer-status.js";
import switchCliProgressStyle from "./progress-bars/switch-cli-progress-style.js";
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/download/download-engine/download-file/download-engine-file.ts
Outdated
Show resolved
Hide resolved
src/download/download-engine/streams/download-engine-write-stream/utils/WriteQueue.ts
Show resolved
Hide resolved
src/download/download-engine/streams/download-engine-write-stream/utils/WriteQueue.ts
Show resolved
Hide resolved
src/download/download-engine/streams/download-engine-write-stream/utils/WriteQueue.ts
Show resolved
Hide resolved
.../download-engine/streams/download-engine-write-stream/download-engine-write-stream-nodejs.ts
Outdated
Show resolved
Hide resolved
BREAKING CHANGE: shortcut '-st' flag is no support anymore use '--style' instead
BREAKING CHANGE: 'size' changed to remoteSize and downloadSize
Description of change
Refactor to some core functionality of ipull that improves download speed and make ipull more light wight.
--saveto directory is hang and saves to current directory #21All the performance benchmarks can be found here
https://ido-pluto.github.io/ipull-speed-test/
https://github.com/ido-pluto/ipull-speed-test
Breaking chage:
Pull-Request Checklist
mainbranchnpm run formatto apply eslint formattingnpm run testpasses with this changeFixes #0000in CONTRIBUTING.md