# LeDown

### A resumable downloader

[![Build Status](https://travis-ci.org/liuxiaole/ledown.svg?branch=master)](https://travis-ci.org/liuxiaole/ledown)
[![Coverage Status](https://coveralls.io/repos/github/liuxiaole/ledown/badge.svg?branch=master)](https://coveralls.io/github/liuxiaole/ledown?branch=master)
[![npm version](https://badge.fury.io/js/ledown.svg)](https://badge.fury.io/js/ledown)

A library for nodejs to download http large file in pauseable and resumable way

## Prerequisite

Node >= 8.0

## Usage

### Commonjs

```js
var Task = require('ledown').Task
Task.create({
  url: 'url',
  downloadPath: 'path'
}).then(function(task) {
  task.on('progress', function(){
    console.log(task.progress)
  })
  task.on('error', function(err) {
    console.log(err)
  })
  task.on('end', function() {
    console.log('end')
  })
  task.start()
})
```
### ES6
```js
import { Task } from 'ledown'
await task = Task.create({
  url: 'url',
  downloadPath: 'path'
})

task.on('progress', () => {
  console.log(task.progress)
})
task.on('error',err => {
  console.log(err)
})
task.on('end', () => {
  console.log('end')
})
task.start()

setTimeout(() => {
  if(task.progress !== 1) {
    task.stop()
      .then(() => {
        task.storeToFile(path.join(__dirname, './task.config'))
      })
  }
}, 1000)
```

## Documentation

### static create(options: TaskOptions): Promise\<Task\>

Static method on Task class for creating a new download task.

```ts
type TaskOptions = {
    url: string
    referUrl?: string
    downloadDir?: string
    downloadPath: string
  } | {
    url: string
    referUrl?: string
    downloadDir: string
    downloadPath?: string
  }
```

You have to specify whether the downloadDir or downloadPath. If you just specify the downloadDir, a random name will be used.

Task.create use HTTP `HEAD` method to get metadata of the resource. If server respond an error, the returned promise will be rejected.

### static restoreFromFile(path: string): Promise\<Task\>

Restore task from previous task config file. If ether the specified config file or the previous unfinished downloading file not exists, the returned promise will be rejected.

### static Task.Error

  + Task.ERROR.ERR_NO_METADATA
  + Task.ERROR.ERR_DISK_IO_WRITE
  + Task.ERROR.ERR_NETWORK

```js
task.on('error', (e) => {
  if(e.message === Task.ERROR.ERR_DISK_IO_WRITE) {
    // write disk error
  } else if(e.message === Task.ERROR.ERR_NETWORK) {
    // download resource error
  }
})
```

### Task#storeToFile(path: string): Promise\<void\>

Store a task config to specified path. IO error will cause the returned promise to be rejected. This method will not stop the task. You could call `task.stop()` as needed.

### Task#start(numOfThread: number = 1): void

Start the task. If you specify the `numOfThread` argument, it will concurrently start multiple http request.

### Task#stop(): Promise\<void\>

Stop the task. We could not stop the task immediately, since we have no method to suspend write task.

### Task#on(event: string, listener: function): void

Events that may triggered:

  + on('error')
  + on('progress')
  + on('end')

### Task#off(event: string, listener: function): void

Remove the listener of the specific event.

### Task#progress: number

Progress of the task. When the task complete, task.progress is 1.

### Task#metadata

The structure of task.metadata is:

  + url: string
  + createDate: Date
  + mimeType: string
  + downloadPath: string
  + totalBytes: number
  + resumable: boolean

## LICENSE

[MIT](https://opensource.org/licenses/MIT)

Copyright (c) 2017-present, Xiaole (Will) Liu
