Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
e09de64
fix(downloadProgram): different default chunk size
ido-pluto Jan 14, 2025
20b66ee
feat: debounce write - faster chunks write
ido-pluto Jan 20, 2025
739ab73
feat: scoped multi download engine
ido-pluto Jan 20, 2025
216ff94
feat: add id to download
ido-pluto Jan 20, 2025
03aca33
feat: Global CLI management
ido-pluto Feb 14, 2025
b394986
feat: Remote CLI progress
ido-pluto Feb 14, 2025
332eff0
fix: load download file metadata
ido-pluto Feb 14, 2025
d71ba6f
chores: beta release
ido-pluto Feb 14, 2025
0d961c3
feat: stream timeout
ido-pluto Feb 14, 2025
3269161
fix: reduce log update
ido-pluto Feb 14, 2025
1f74705
fix: formatting
ido-pluto Feb 14, 2025
e9dbe2f
fix: xhr stream timeout
ido-pluto Feb 15, 2025
8eb5ea4
fix: local file tests
ido-pluto Feb 15, 2025
db22eda
fix: downloadSequence signature
ido-pluto Feb 15, 2025
0d6184c
docs: update readme
ido-pluto Feb 15, 2025
bbec167
feat: auto increase parallel stream
ido-pluto Feb 26, 2025
23b28e7
chores: ci prerelease
ido-pluto Feb 26, 2025
e89e40e
chores: fix ci
ido-pluto Feb 26, 2025
42e3d10
chores: fix ci
ido-pluto Feb 26, 2025
054e4bf
chores: fix ci
ido-pluto Feb 26, 2025
e036715
chores: node 23 ci
ido-pluto Feb 26, 2025
e1e7ffa
chores: node 22 ci
ido-pluto Feb 26, 2025
378c7a6
feat: long stream timeout
ido-pluto Feb 26, 2025
051ab50
fix(fetch): throw error
ido-pluto Feb 26, 2025
f2e979e
ci: fix release
ido-pluto Feb 26, 2025
8989049
docs(README): automatic parallelization
ido-pluto Mar 2, 2025
a75e668
fix(fetch): abort streaming
ido-pluto Mar 2, 2025
907f525
fix(save): prevent save emit after finished
ido-pluto Mar 2, 2025
646cdbd
fix(types): export required types
ido-pluto Mar 2, 2025
0a25b7b
fix(multi-download): race condition
ido-pluto Mar 9, 2025
f791886
fix(chunk-split): validate leftover
ido-pluto Mar 11, 2025
022ca6a
perf(chunks): send write event only once for chunk
ido-pluto Mar 12, 2025
1024941
fix(dynamic-length): send the last chunk of dynamic length
ido-pluto Mar 12, 2025
698ddf9
fix(globalCLI): cli hook on non-active download
ido-pluto Mar 16, 2025
903a3ab
chores: Use polyfill for Promise.withResolvers to support older versi…
ido-pluto May 22, 2025
f12b2f6
feat(redirect): do not flow redirect by default, prevent token expires
ido-pluto May 22, 2025
c31e008
chores: fix ts config
ido-pluto May 22, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,19 @@ jobs:
- name: Generate docs
run: npm run generate-docs
- name: Upload build artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: "build"
path: "dist"
- name: Upload build artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: "docs"
path: "docs"

release:
name: Release
if: github.ref == 'refs/heads/main'
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/beta'
runs-on: ubuntu-latest
concurrency: release-${{ github.ref }}
environment:
Expand All @@ -52,10 +52,10 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: "20"
node-version: "22"
- name: Install modules
run: npm ci --ignore-scripts
- uses: actions/download-artifact@v3
- uses: actions/download-artifact@v4
with:
path: artifacts
- name: Move artifacts
Expand All @@ -73,16 +73,16 @@ jobs:
id: set-npm-url
run: |
if [ -f .semanticRelease.npmPackage.deployedVersion.txt ]; then
echo "npm-url=https://www.npmjs.com/package/node-llama-cpp/v/$(cat .semanticRelease.npmPackage.deployedVersion.txt)" >> $GITHUB_OUTPUT
echo "npm-url=https://www.npmjs.com/package/ipull/v/$(cat .semanticRelease.npmPackage.deployedVersion.txt)" >> $GITHUB_OUTPUT
fi
- name: Upload docs to GitHub Pages
if: steps.set-npm-url.outputs.npm-url != ''
uses: actions/upload-pages-artifact@v2
uses: actions/upload-pages-artifact@v3
with:
name: pages-docs
path: docs
- name: Deploy docs to GitHub Pages
if: steps.set-npm-url.outputs.npm-url != ''
uses: actions/deploy-pages@v2
if: steps.set-npm-url.outputs.npm-url != '' && github.ref == 'refs/heads/main'
uses: actions/deploy-pages@v4
with:
artifact_name: pages-docs
6 changes: 5 additions & 1 deletion .releaserc.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
{
"branches": [
"main"
"main",
{
"name": "beta",
"prerelease": true
}
],
"ci": true,
"plugins": [
Expand Down
42 changes: 35 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ npx ipull http://example.com/file.large
## Features

- Download using parallels connections
- Maximize download speed (automatic parallelization, 3+)
- Pausing and resuming downloads
- Node.js and browser support
- Smart retry on fail
Expand Down Expand Up @@ -73,8 +74,9 @@ import {downloadFileBrowser} from "ipull/dist/browser.js";

const downloader = await downloadFileBrowser({
url: 'https://example.com/file.large',
onWrite: (cursor: number, buffer: Uint8Array, options) => {
console.log(`Writing ${buffer.length} bytes at cursor ${cursor}, with options: ${JSON.stringify(options)}`);
onWrite: (cursor: number, buffers: Uint8Array[], options) => {
const totalLength = buffers.reduce((acc, buffer) => acc + buffer.length, 0);
console.log(`Writing ${totalLength} bytes at cursor ${cursor}, with options: ${JSON.stringify(options)}`);
}
});

Expand Down Expand Up @@ -234,12 +236,12 @@ If the maximum reties was reached the download will fail and an error will be th
```ts
import {downloadFile} from 'ipull';

const downloader = await downloadFile({
url: 'https://example.com/file.large',
directory: './this/path'
});

try {
const downloader = await downloadFile({
url: 'https://example.com/file.large',
directory: './this/path'
});

await downloader.download();
} catch (error) {
console.error(`Download failed: ${error.message}`);
Expand All @@ -250,6 +252,8 @@ try {

In some edge cases, the re-try mechanism may give the illusion that the download is stuck.

(You can see this in the progress object that "retrying" is true)

To debug this, disable the re-try mechanism:

```js
Expand All @@ -258,6 +262,9 @@ const downloader = await downloadFile({
directory: './this/path',
retry: {
retries: 0
},
retryFetchDownloadInfo: {
retries: 0
}
});
```
Expand Down Expand Up @@ -286,6 +293,27 @@ downloader.on("progress", (progress) => {
});
```

### Remote Download Listing

If you want to show in the CLI the progress of a file downloading in remote.

```ts
const originaldownloader = await downloadFile({
url: 'https://example.com/file.large',
directory: './this/path'
});

const remoteDownloader = downloadFileRemote({
cliProgress: true
});

originaldownloader.on("progress", (progress) => {
remoteDownloader.emitRemoteProgress(progress);
});

await originaldownloader.download();
```

### Download multiple files

If you want to download multiple files, you can use the `downloadSequence` function.
Expand Down
7 changes: 4 additions & 3 deletions examples/browser-log.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import {downloadFileBrowser} from "ipull/dist/browser.js";
import {downloadFileBrowser} from "ipull/browser";

const BIG_IMAGE = "https://upload.wikimedia.org/wikipedia/commons/9/9e/1_dubrovnik_pano_-_edit1.jpg"; // 40mb

const downloader = await downloadFileBrowser({
url: BIG_IMAGE,
onWrite: (cursor: number, buffer: Uint8Array, options) => {
console.log(`Writing ${buffer.length} bytes at cursor ${cursor}, with options: ${JSON.stringify(options)}`);
onWrite: (cursor: number, buffers: Uint8Array[], options: DownloadEngineWriteStreamOptionsBrowser) => {
const totalLength = buffers.reduce((acc, b) => acc + b.byteLength, 0);
console.log(`Writing ${totalLength} bytes at cursor ${cursor}, with options: ${JSON.stringify(options)}`);
}
});

Expand Down
68 changes: 46 additions & 22 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@
"sleep-promise": "^9.1.0",
"slice-ansi": "^7.1.0",
"stdout-update": "^4.0.1",
"strip-ansi": "^7.1.0"
"strip-ansi": "^7.1.0",
"uid": "^2.0.2"
}
}
19 changes: 13 additions & 6 deletions src/browser.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {downloadFileBrowser, DownloadFileBrowserOptions, downloadSequenceBrowser} from "./download/browser-download.js";
import {downloadFileBrowser, DownloadFileBrowserOptions, downloadFileRemoteBrowser, downloadSequenceBrowser, DownloadSequenceBrowserOptions} from "./download/browser-download.js";
import DownloadEngineBrowser from "./download/download-engine/engine/download-engine-browser.js";
import EmptyResponseError from "./download/download-engine/streams/download-engine-fetch-stream/errors/empty-response-error.js";
import StatusCodeError from "./download/download-engine/streams/download-engine-fetch-stream/errors/status-code-error.js";
Expand All @@ -9,17 +9,21 @@ import FetchStreamError from "./download/download-engine/streams/download-engine
import IpullError from "./errors/ipull-error.js";
import EngineError from "./download/download-engine/engine/error/engine-error.js";
import {FormattedStatus} from "./download/transfer-visualize/format-transfer-status.js";
import DownloadEngineMultiDownload from "./download/download-engine/engine/download-engine-multi-download.js";
import DownloadEngineMultiDownload, {DownloadEngineMultiAllowedEngines} from "./download/download-engine/engine/download-engine-multi-download.js";
import HttpError from "./download/download-engine/streams/download-engine-fetch-stream/errors/http-error.js";
import BaseDownloadEngine from "./download/download-engine/engine/base-download-engine.js";
import {InvalidOptionError} from "./download/download-engine/engine/error/InvalidOptionError.js";
import {DownloadFlags, DownloadStatus} from "./download/download-engine/download-file/progress-status-file.js";
import {NoDownloadEngineProvidedError} from "./download/download-engine/engine/error/no-download-engine-provided-error.js";
import {DownloadEngineRemote} from "./download/download-engine/engine/DownloadEngineRemote.js";
import {
DownloadEngineWriteStreamOptionsBrowser
} from "./download/download-engine/streams/download-engine-write-stream/download-engine-write-stream-browser.js";

export {
DownloadFlags,
DownloadStatus,
downloadFileBrowser,
downloadFileRemoteBrowser,
downloadSequenceBrowser,
EmptyResponseError,
HttpError,
Expand All @@ -29,15 +33,18 @@ export {
FetchStreamError,
IpullError,
EngineError,
InvalidOptionError,
NoDownloadEngineProvidedError
InvalidOptionError
};

export type {
DownloadEngineRemote,
BaseDownloadEngine,
DownloadFileBrowserOptions,
DownloadEngineBrowser,
DownloadEngineMultiDownload,
DownloadEngineMultiAllowedEngines,
FormattedStatus,
SaveProgressInfo
SaveProgressInfo,
DownloadSequenceBrowserOptions,
DownloadEngineWriteStreamOptionsBrowser
};
Loading
Loading