Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
145 changes: 72 additions & 73 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ JavaScript (Node.js and browsers) library for [aria2, "The next generation downl
- [Introduction](#introduction)
- [Getting started](#getting-started)
- [Usage](#usage)
- [open](#open)
- [close](#close)
- [call](#call)
- [multicall](#multicall)
- [batch](#batch)
- [open](#open)
- [close](#close)
- [listNotifications](#listnotifications)
- [listMethods](#listmethods)
- [events](#events)
Expand All @@ -19,19 +19,17 @@ JavaScript (Node.js and browsers) library for [aria2, "The next generation downl

aria2.js controls aria2 via its [JSON-RPC interface](https://aria2.github.io/manual/en/html/aria2c.html#rpc-interface) and features

- Node.js and browsers support
- multiple transports
- [HTTP](https://aria2.github.io/manual/en/html/aria2c.html#rpc-interface)
- [WebSocket](https://aria2.github.io/manual/en/html/aria2c.html#json-rpc-over-websocket)
- promise API
- support for browsers, Node.js, React Native, deno and gjs environments
- support for [HTTP](https://aria2.github.io/manual/en/html/aria2c.html#rpc-interface) and [WebSocket](https://aria2.github.io/manual/en/html/aria2c.html#json-rpc-over-websocket) transports
- modern ECMAScript API

See [aria2 methods](https://aria2.github.io/manual/en/html/aria2c.html#methods) and [aria2 notifications](https://aria2.github.io/manual/en/html/aria2c.html#notifications).
See [aria2 methods](https://aria2.github.io/manual/en/html/aria2c.html#methods) and [aria2 notifications](https://aria2.github.io/manual/en/html/aria2c.html#notifications) to get an idea of what aria2 and aria2.js are capable of.

[↑](#aria2js)

## Getting started

Start aria2 with rpc, example:
Start aria2 in daemon mode with rpc, example:

`aria2c --enable-rpc --rpc-listen-all=true --rpc-allow-origin-all`

Expand All @@ -46,6 +44,8 @@ Install aria2.js
```javascript
const Aria2 = require("aria2");
const aria2 = new Aria2([options]);
aria2.onerror = console.error;
aria2.onnotification = console.log;
```

default options match aria2c defaults and are
Expand All @@ -64,34 +64,6 @@ default options match aria2c defaults and are

If the WebSocket is open (via the [open method](#open)) aria2.js will use the WebSocket transport, otherwise the HTTP transport.

The `"aria2."` prefix can be omitted from both methods and notifications.

[↑](#aria2js)

### open

`aria2.open()` opens the WebSocket connection. All subsequent requests will use the WebSocket transport instead of HTTP.

```javascript
aria2
.open()
.then(() => console.log("open"))
.catch((err) => console.log("error", err));
```

[↑](#aria2js)

### close

`aria2.close()` closes the WebSocket connection. All subsequent requests will use the HTTP transport instead of WebSocket.

```javascript
aria2
.close()
.then(() => console.log("closed"))
.catch((err) => console.log("error", err));
```

[↑](#aria2js)

### call
Expand All @@ -103,7 +75,7 @@ Example using [`addUri`](https://aria2.github.io/manual/en/html/aria2c.html#aria
```javascript
const magnet =
"magnet:?xt=urn:btih:88594AAACBDE40EF3E2510C47374EC0AA396C08E&dn=bbb_sunflower_1080p_30fps_normal.mp4&tr=udp%3a%2f%2ftracker.openbittorrent.com%3a80%2fannounce&tr=udp%3a%2f%2ftracker.publicbt.com%3a80%2fannounce&ws=http%3a%2f%2fdistribution.bbb3d.renderfarming.net%2fvideo%2fmp4%2fbbb_sunflower_1080p_30fps_normal.mp4";
const [guid] = await aria2.call("addUri", [magnet], { dir: "/tmp" });
const guid = await aria2.call("addUri", [magnet], { dir: "/tmp" });
```

[↑](#aria2js)
Expand All @@ -121,6 +93,8 @@ const multicall = [
const results = await aria2.multicall(multicall);
```

[↑](#aria2js)

### batch

`aria2.batch()` is a helper for [batch](https://aria2.github.io/manual/en/html/aria2c.html#system.multicall). It behaves the same as [multicall](#multicall) except it returns an array of promises which gives more flexibility in handling errors.
Expand All @@ -136,6 +110,32 @@ const promises = await aria2.batch(batch);

[↑](#aria2js)

### open

`aria2.open()` opens the WebSocket connection. All subsequent requests will use the WebSocket transport instead of HTTP.

```javascript
aria2
.open()
.then(() => console.log("open"))
.catch((err) => console.log("error", err));
```

[↑](#aria2js)

### close

`aria2.close()` closes the WebSocket connection. All subsequent requests will use the HTTP transport instead of WebSocket.

```javascript
aria2
.close()
.then(() => console.log("closed"))
.catch((err) => console.log("error", err));
```

[↑](#aria2js)

### listNotifications

`aria2.listNotifications()` is a helper for [system.listNotifications](https://aria2.github.io/manual/en/html/aria2c.html#system.listNotifications). The difference with `aria2.call('listNotifications')` is that it removes the `"aria2."` prefix from the results.
Expand All @@ -152,20 +152,13 @@ const notifications = await aria2.listNotifications();
'onBtDownloadComplete'
]
*/

// notifications logger example
notifications.forEach((notification) => {
aria2.on(notification, (params) => {
console.log("aria2", notification, params);
});
});
```

[↑](#aria2js)

### listMethods

`aria2.listMethods()` is a helper for [system.listMethods](https://aria2.github.io/manual/en/html/aria2c.html#system.listMethods). The difference with `aria2.call('listMethods')` is that it removes the `"aria2."` prefix for the results.
`aria2.listMethods()` is a helper for [system.listMethods](https://aria2.github.io/manual/en/html/aria2c.html#system.listMethods). The difference with `aria2.call('listMethods')` is that it removes the `"aria2."` prefix from the results.

```javascript
const methods = await aria2.listMethods();
Expand All @@ -182,33 +175,39 @@ const methods = await aria2.listMethods();
### events

```javascript
// emitted when the WebSocket is open.
aria2.on("open", () => {
console.log("aria2 OPEN");
});

// emitted when the WebSocket is closed.
aria2.on("close", () => {
console.log("aria2 CLOSE");
});

// emitted for every message sent.
aria2.on("output", (m) => {
console.log("aria2 OUT", m);
});

// emitted for every message received.
aria2.on("input", (m) => {
console.log("aria2 IN", m);
});
```

Additionally every [aria2 notifications](https://aria2.github.io/manual/en/html/aria2c.html#notifications) received will be emitted as an event (with and without the `"aria2."` prefix). Only available when using WebSocket, see [open](#open).

```javascript
aria2.on("onDownloadStart", ([guid]) => {
console.log("aria2 onDownloadStart", guid);
});
// called when an error occurs
aria2.onerror = (error) => {
console.log("aria2", "ERROR");
console.log(error);
};

// called when a notification is received on the WebSocket
aria2.onnotification = (name, params) => {
console.log("aria2", "notification", name);
console.log(params);
};

// called when the WebSocket is open.
aria2.onopen = () => {
console.log("aria2", "OPEN");
};

// called when the WebSocket is closed.
aria2.onclose = () => {
console.log("aria2", "CLOSE");
};

// called for every message received.
aria2.oninput = (message) => {
console.log("aria2", "IN");
console.log(message);
};

// called for every message sent.
aria2.onoutput = (message) => {
console.log("aria2", "OUT");
console.log(message);
};
```

[↑](#aria2js)
59 changes: 31 additions & 28 deletions lib/Aria2.js
Original file line number Diff line number Diff line change
@@ -1,41 +1,29 @@
import JSONRPCClient from "./JSONRPCClient.js";

function prefix(str) {
if (!str.startsWith("system.") && !str.startsWith("aria2.")) {
str = "aria2." + str;
}
return str;
}

function unprefix(str) {
const suffix = str.split("aria2.")[1];
return suffix || str;
}

class Aria2 extends JSONRPCClient {
addSecret(parameters) {
_withSecret(parameters) {
let params = this.secret ? ["token:" + this.secret] : [];
if (Array.isArray(parameters)) {
params = params.concat(parameters);
}
return params;
}

_onnotification(notification) {
_handleNotification(notification) {
const { method, params } = notification;
const event = unprefix(method);
if (event !== method) this.emit(event, params);
return super._onnotification(notification);
this._signal([event, params]);
super._handleNotification(notification);
}

async call(method, ...params) {
return super.call(prefix(method), this.addSecret(params));
return super.call(prefix(method), this._withSecret(params));
}

async multicall(calls) {
const multi = [
calls.map(([method, ...params]) => {
return { methodName: prefix(method), params: this.addSecret(params) };
return { methodName: prefix(method), params: this._withSecret(params) };
}),
];
return super.call("system.multicall", multi);
Expand All @@ -45,7 +33,7 @@ class Aria2 extends JSONRPCClient {
return super.batch(
calls.map(([method, ...params]) => [
prefix(method),
this.addSecret(params),
this._withSecret(params),
])
);
}
Expand All @@ -61,14 +49,29 @@ class Aria2 extends JSONRPCClient {
}
}

Object.assign(Aria2, { prefix, unprefix });

Aria2.defaultOptions = Object.assign({}, JSONRPCClient.defaultOptions, {
secure: false,
host: "localhost",
port: 6800,
secret: "",
path: "/jsonrpc",
});
Aria2.defaultOptions = {
...JSONRPCClient.defaultOptions,
...{
secure: false,
host: "localhost",
port: 6800,
secret: "",
path: "/jsonrpc",
},
};

export default Aria2;

function prefix(str) {
if (!str.startsWith("system.") && !str.startsWith("aria2.")) {
str = "aria2." + str;
}
return str;
}

function unprefix(str) {
const suffix = str.split("aria2.")[1];
return suffix || str;
}

Object.assign(Aria2, { prefix, unprefix });
Loading