npm package: @j-o-r/cache
Description: A simple cache/file write/read class, extended JSON for storing typed arrays as json
Author: Jorrit Duin
Latest version: 1.2.7

## @j-o-r/cache

### Introduction

The `@j-o-r/cache` package provides utilities for creating a key-value storage system that respects typed arrays. It offers both synchronous (`CacheSync`) and asynchronous (`CacheAsync`) versions for managing cache entries.

### Installation

To use the `@j-o-r/cache` package, install it via npm:

```bash
npm install @j-o-r/cache
```

### Usage

#### Synchronous Version (CacheSync)

Use `CacheSync` for immediate file operations:

```javascript
import { CacheSync } from '@j-o-r/cache';

const cache = new CacheSync('storage/tmp', true, 'log', 'ascii');
```

#### Asynchronous Version (CacheAsync)

Use `CacheAsync` for non-blocking file operations:

```javascript
import { CacheAsync } from '@j-o-r/cache';

const cache = new CacheAsync('storage/tmp', true, 'log', 'ascii');
```

Use typed arrays

```javascript
import { CacheAsync, JSONEXT } from '@j-o-r/cache';

const cache = new CacheAsync('storage/tmp', true);
cache.jsonEncoder = JSONEXT;
const data = new Uint32Array([1, 2, 3, 4, 5]);
// write a typed array 
await c.write('typed_array', data);
```
### Methods

Both `CacheSync` and `CacheAsync` provide the following methods:

- **`list()`**: Returns an array of all keys in the cache folder.

- **`write(key, value)`**: Writes a value to the cache with the given key. If the value is not a string and the extension is not `json` or `ndjson`, it throws an error.

- **`append(key, value)`**: Appends a value to the cache with the given key. If the value is not a string or if JSON is used without the `ndjson` extension, it throws an error.

- **`read(key)`**: Reads a value from the cache with the given key. If async, use `await`. Returns `undefined` if no file exists.

- **`writeStream(key)`**: Returns a writable stream. For writing large amounts of data   

- **`readStream(key)`**: Returns a readable stream for reading large file. 

- **`file(key)`**: Returns a `CacheFile` object with details about file path, encoding, and existence status.

- **`delete(key)`**: Deletes a file from the cache with the given key.

- **`empty()`**: Empties all files in the cache folder.

- **`expire(time)`**: Deletes files older than specified time (in milliseconds).

- **`secret = [string]`** Encrypt the content written to the files with this 'secret'.

- **`encoding = [string]`** Force an encoding (for binaries e.g.) default 'uft-8'.

- **`**sanitizeKey(key)`** returns a valid key. Make sure a key is valid as a storage location (filename).

- **`**md5Key(key)`** returns a valid key in the form of a MD5 hash.

- **`expire(value)`** Delete all keys who are older (last changed) then the number of MS given as value.

### Example

**Synchronous Example:**

```javascript
const syncCache = new CacheSync('storage/tmp');

syncCache.write('key', 'value');
const syncValue = syncCache.read('key');
syncCache.delete('key');
syncCache.empty();
```

**Asynchronous Example:**

```javascript
const asyncCache = new CacheAsync('storage/tmp');

await asyncCache.write('key', 'value');
const asyncValue = await asyncCache.read('key');
await asyncCache.delete('key');
await asyncCache.empty();
```

#### Read/Write streams

- **Writing Data with Streams:**
  ```javascript
  const writable = cache.writeStream('large_key_file');
  writable.write('Some large data...');
  writable.end();
  ```

- **Reading Data with Streams:**
  ```javascript
  const readable = cache.readStream('large_key_file');
  readable.on('data', (chunk) => {
      console.log(`Received ${chunk.length} bytes of data.`);
  });
  ```


### Encryption Example

To enable encryption for both versions:

```javascript
// For both Sync and Async:
cache.secret = 'mySecretKey';

// Write encrypted data:
cache.write('key', 'sensitive data');

// Read and decrypt data:
let decryptedValue;
if (cache instanceof CacheSync) {
    decryptedValue = cache.read('key'); // Synchronous read
} else {
    decryptedValue = await cache.read('key'); // Asynchronous read with await
}
console.log(decryptedValue); // Outputs: 'sensitive data'
```

### Features

- Supports typed arrays when stored as JSON.
- Custom file extensions are allowed.
- Methods for listing, writing, reading, appending, deleting, emptying caches.

## License

This project is licensed under APACHE 2.0 License. See LICENSE file for details.