npm package: @plaindb/drive
Description: An isomorphic, streamable and datastore agnostic library for efficient and flexible file storage management.
Author: Basedwon
Latest version: 0.0.0

# Drive

[![npm](https://img.shields.io/npm/v/@plaindb/drive?style=flat&logo=npm)](https://www.npmjs.com/package/@plaindb/drive)
[![pipeline](https://gitlab.com/frenware/framework/plaindb/drive/badges/master/pipeline.svg)](https://gitlab.com/frenware/framework/plaindb/drive/-/pipelines)
[![license](https://img.shields.io/npm/l/@plaindb/drive)](https://gitlab.com/frenware/framework/plaindb/drive/-/blob/master/LICENSE)
[![downloads](https://img.shields.io/npm/dw/@plaindb/drive)](https://www.npmjs.com/package/@plaindb/drive) 

[![Gitlab](https://img.shields.io/badge/Gitlab%20-%20?logo=gitlab&color=%23383a40)](https://gitlab.com/frenware/framework/plaindb/drive)
[![Twitter](https://img.shields.io/badge/@basdwon%20-%20?logo=twitter&color=%23383a40)](https://twitter.com/basdwon)
[![Discord](https://img.shields.io/badge/Basedwon%20-%20?logo=discord&color=%23383a40)](https://discordapp.com/users/basedwon)

An isomorphic library for efficient and flexible file storage management. It uses chunk-based storage, stream support, and batch operations for optimized performance and data integrity. The library is agnostic to the storage backend, accepting any datastore through dependency injection.

## Features

- Write, read and delete file operations.
- Chunk-based storage for better memory utilization.
- Pluggable storage backends.
- Stream support for write and read operations.
- Support for batch operations to commit multiple changes atomically.

## Installation

Install the package with:

```bash
npm install @plaindb/drive
```

## Usage

First, import the `Drive` library.

```js
import Drive from '@plaindb/drive'
```
or
```js
const Drive = require('@plaindb/drive')
```

### Basic Setup

You can create an instance of `Drive` using your own storage backend.

```js
const Drive = require('@plaindb/drive')
const storage = /* your storage instance here */
const drive = new Drive(storage)
```

### Options

The `Drive` constructor accepts an optional second argument to specify various settings:

```js
new Drive(storage, {
  chunkSize: 8192, // Size of each file chunk in bytes (16kb default)
  hashLength: 8    // Length of the hash generated from each chunk (32 default)
})
```

## API Documentation

### Writing, Reading, and Deleting Files

For standard file operations, you can use the following methods:

- `drive.writeFile(fid, buffer)`: Writes a buffer to the file.
- `drive.readFile(fid)`: Reads a file and returns a buffer.
- `drive.deleteFile(fid)`: Deletes the file.

Example:

```js
const buffer = Buffer.from('Hello, world!')
await drive.writeFile('fileID', buffer)
const readBuffer = await drive.readFile('fileID')
console.log(readBuffer.toString())
await drive.deleteFile('fileID')
```

### Stream Operations

For handling large files, you can use streams:

- `drive.createWriteStream(fid, opts)`: Creates a writable stream.
- `drive.createReadStream(fid, opts)`: Creates a readable stream.

Example:

```js
const ws = drive.createWriteStream('fileID')
ws.write('Hello, ')
ws.write('world!')
ws.end()

const rs = drive.createReadStream('fileID')
rs.on('data', chunk => {
  console.log(chunk.toString())
})
```

### Advanced Operations

- `drive.commit(ops, chunks)`: Commits a batch of operations atomically.
- `drive.sub(path, opts)`: Creates a sub-storage for scoped file operations.

## Documentation

- [API Reference](/docs/api.md)

### `buildWriteFile(fid, buffer, ops = [], chunks = {})`

Builds the operations required to write a file to the storage but does not commit them.

### `writeFile(fid, buffer)`

Writes a file to the storage.

### `buildDeleteFile(fid, ops = [], chunks = [])`

Builds the operations required to delete a file but does not commit them.

### `deleteFile(fid)`

Deletes a file from the storage.

### `commit(ops, chunks = {})`

Commits a batch of operations atomically.

### `readFile(fid)`

Reads a file from the storage.

### `createWriteStream(fid, opts = {})`

Returns a writable stream for the specified file.

### `createReadStream(fid, opts = {})`

Returns a readable stream for the specified file.

### `sub(path, opts)`

Creates a sub-storage and returns a new `Drive` instance for it.

## Tests

In order to run the test suite, simply clone the repository and install its dependencies:

```bash
git clone https://gitlab.com/frenware/framework/plaindb/drive.git
cd drive
npm install
```

To run the tests:

```bash
npm test
```

## Contributing

Thank you! Please see our [contributing guidelines](/docs/contributing.md) for details.

## Donations

If you find this project useful and want to help support further development, please send us some coin. We greatly appreciate any and all contributions. Thank you!

**Bitcoin (BTC):**
```
1JUb1yNFH6wjGekRUW6Dfgyg4J4h6wKKdF
```

**Monero (XMR):**
```
46uV2fMZT3EWkBrGUgszJCcbqFqEvqrB4bZBJwsbx7yA8e2WBakXzJSUK8aqT4GoqERzbg4oKT2SiPeCgjzVH6VpSQ5y7KQ
```

## License

@plaindb/drive is [MIT licensed](https://gitlab.com/frenware/framework/plaindb/drive/-/blob/master/LICENSE).