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.
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