# artefact-store

> a hyperdrive based blob store which supports encryption, streaming, ...

Latest version **1.4.0** (published 2024-02-18) · AGPL-3.0 license · 0 weekly downloads

## Install

```sh
npm install artefact-store
pnpm add artefact-store
yarn add artefact-store
bun add artefact-store
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 1.4.0 |
| Published | 2024-02-18 |
| First published | 2021-02-23 |
| Weekly downloads | 0 |
| License | AGPL-3.0 |
| TypeScript types | none |
| Module format | CommonJS |
| Node | <16 \|\| >=18 |
| Dependencies | 7 |
| Unpacked size | 60.6 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | peg + mu |
| Maintainers | powersource, ben-tai, chereseeriepa, mixmix |

## Links

- npm: https://www.npmjs.com/package/artefact-store
- Repository: https://gitlab.com/ahau/artefact-store
- Issues: https://gitlab.com/ahau/artefact-store/issues
- npm.io page: https://npm.io/package/artefact-store

## Dependencies (7)

- [obz](https://npm.io/package/obz.md) ^1.1.0
- [debug](https://npm.io/package/debug.md) ^4.3.1
- [corestore](https://npm.io/package/corestore.md) ^5.8.2
- [hyperdrive](https://npm.io/package/hyperdrive.md) ^10.20.0
- [sodium-native](https://npm.io/package/sodium-native.md) ^3.2.0
- [random-access-file](https://npm.io/package/random-access-file.md) ^2.2.1
- [@corestore/networker](https://npm.io/package/@corestore/networker.md) ^1.2.0

## Recent versions

- 1.4.0 (latest) — 2024-02-18
- 1.3.2 — 2023-04-28
- 1.3.1 — 2023-02-28
- 1.3.0 — 2021-07-05
- 1.2.1 — 2021-06-13
- 1.2.0 — 2021-05-25
- 1.1.0 — 2021-05-17
- 1.0.0 — 2021-03-26
- 0.2.1 — 2021-03-07
- 0.2.0 — 2021-03-01
- 0.1.0 — 2021-02-23

## README

# artefact-store 

This is a small module that will plug into the back-end of Ahau for the storage and retrieval of 'artefacts': text, image, audio or video files.

## Example Usage

```js
async function main () {
  const alice = new ArtefactStore('./alice')
  await alice.ready()
  const inputFile = path.join(path.resolve(__dirname), './README.md')

  const { fileName, fileEncryptionKey } = await alice.addFile(inputFile)
  const readStream = await alice.getReadStream(fileName, alice.driveAddress, fileEncryptionKey)
  readStream.pipe(process.stdout)
  alice.close()
}
```

## API

### `new ArtefactStore(storagePath, options) => artefactStore`

Create a new `artefactStore` instance.
- `storagePath` can be either a string or a random-access-storage module.
- `options` is an optional object which may include:
    - `pataka' *Boolean* 
        - control if this is a pataka store or a general artefact store. Patakas don't maintain a personal drive, and replicate all other drives fully
        - (default: false)
    - `bootstrap` *Array*
        - an collection of addresses of form `host:port` used as DHT bootstrap nodes
        - default:
          ```js
          [
            'bootstrap1.hyperdht.org:49737',
            'bootstrap2.hyperdht.org:49737',
            'bootstrap3.hyperdht.org:49737'
          ]
          ```
        - to run your own DHT nodes see https://github.com/hyperswarm/dht
    - (advanced: you can also pass options which for: [@corestore/networker](https://www.npmjs.com/package/@corestore/networker) and [hyperswarm](https://github.com/hyperswarm/hyperswarm))

### `ArtefactStore.artefactEncryptionKey() => Buffer`

Static function which generates a unique key for encrypting each message that is added to a user's own artefactStore. Returns a buffer.

### Getters

### `artefactStore.driveAddress => String`

Returns the driveAddress (as a String) for this instance.

see more https://github.com/hypercore-protocol/hypercore#feedkey

### `artefactStore.discoveryKey => String`

Returns the discoveryKey (as a String) for this instance.

see more https://github.com/hypercore-protocol/hypercore#feeddiscoverykey

### `artefactStore.remoteDrives => [HyperDrive]`

Lists the remote drives we are currently tracking, returns an Array of HyperDrives.

> Note: `HyperDrive.key = driveAddress`

### `artefactStore.ready() => Promise`

Call after instantiating ArtefactStore, ensures user's own drive keys are correctly recorded. Returns a promise which resolves when artefactStore is fully initialised.

### `artefactStore.addFile(localFilename, options) => Promise`

Add a file from the local filesystem. This method calls `createWriteStream` and `update` internally.
- `localFilename` - full path of the local file
- `options` - an optional object which may contain properties:
  - `optionalFileEncryptionKey`, which should be a buffer. If not given, a new encryption key will be created.
  - `targetFileName`, the file name to use on the drive.  If not given, the base filename of the local file will be used.
Returns a promise which resolves to an object with properties:
- `driveAddress` - the drive used (always the same, returned for convenience)
- `fileName` - the filepath on the drive
- `fileEncryptionKey` the encryption key used

### `artefactStore.addFileStream(fileStream, fileName, options) => Promise`

Add a file from a readstream. This method calls `createWriteStream` and `update` internally.
- `fileSourceStream` - readstream of the file to add
- `fileName` - name of the file to add
- `options` - an optional object which may contain properties:
  - `optionalFileEncryptionKey`, which should be a buffer. If not given, a new encryption key will be created.
Returns a promise which resolves to an object with properties:
- `driveAddress` - the drive used (always the same, returned for convenience)
- `fileName` - the filepath on the drive
- `fileEncryptionKey` the encryption key used

### `artefactStore.createWriteStream(artefactFileName, artefactEncryptionKey, opts)`

Prepare to write a file to one of a user's own drives within their artefactStore. 
- `artefactFileName` should be a string. Note this needs to be unique for your drive.
- `artefactEncryptionKey` is a unique key required to encrypt the message being written. Should either be a string encoded in hex or a buffer.
- `opts` is an optional object that could contain the same options offered by fs.createWriteStream.

### `artefactStore.getReadStream(artefactFileName, driveAddress, artefactEncryptionKey, opts = {}) => Promise`

Prepare to read a file from a particular drive within an artefactStore. Unlike createReadStream, this returns a promise which, when resolved, will give a stream.
- `artefactFileName` should be a string.
- `driveAddress` should either be a string encoded in hex or a buffer.
- `artefactEncryptionKey` is a unique key required to decrypt the message being read. Should either be a string encoded in hex or a buffer.
- `opts` is an optional object. As with fs.createReadStream, it can contain `start: number` to indicate the position in a given file at which to start the readstream, and `end: number` to indicate the position in a given file at which to stop the readstream.

### `artefactStore.getFilesByDrive(directoryPath, driveAddress) => Promise`

Lists a directory from a particular drive within an artefactStore.

- `directoryPath` (optional) should be a string, if not provided defaults to the root directory.
- `driveAddress` (optional) should be either a string encoded in hex or a buffer, if not provided defaults to the driveAddress of your own drive.

### `artefactStore.update(fileName) => Promise`

When writing to a hyperdrive, this method ensures the hyperdrive has updated and the file `fileName` is accessible once written.


### `artefactStore._replicate(isInitiator, opts)`

Internal method. Replicates one user's artefactStore to another's. `isInitiator` should be `true` for the artefactStore initiating the exchange, and `false` for the artefactStore responding. Returns a stream. Note: this is currently not used in this module, as corestore-networker does this internally, but is available in case it is desirable to have another method of replicating from peers.

`await artefactStore.remove(artefactFileName, driveAddress)`

Given an artefactFileName and its driveAddress, deletes the local copy of the file. Used to clear space on local device. NB this method does not check that there is another copy of the file existing on the network - ie. that this is not the only existing copy.

### `artefactStore.close() => Promise`

Gracefully closes connections to peers.

### `artefactStore.fileStats(artefactFileName, driveAddress) => Promise`

Given an artefactFileName and its driveAddress, returns the stats of the file, similar to `fs.stats`. See more https://github.com/hypercore-protocol/hyperdrive#drivestatname-options-callback

### `artefactStore.fileSize(artefactFileName, driveAddress) => Promise`

Given an artefactFileName and its driveAddress, returns the size in bytes of the file.
Useful for telling the browser the size of a file so that it can effectively skip within the file while streaming.

NOTE: becuase artefact-store encrypts with a streaming cypher, the file size of the original file is the same as that of the encypted file.

### `artefactStore.driveSize(driveAddress) => Promise`

Given a driveAddress, returns the size in bytes of the locally stored copy of the drive.

### `artefactStore.getConnectedPeersForDrive(driveAddress) => Promise`

Given a drive address, returns an array of peer objects representing peers connected to that drive.
- `driveAddress` should be a 32 byte buffer or hex encoded string.  If not given and not in pataka mode, will return peers connected to your own drive.

## Events

### `'peer-add'`

Emitted when a new peer connects to any drive.  Called with a peer object which contains connection information.

### `'peer-remove'`

Emitted when a new peer disconnects from any drive.  Called with a peer object which contains connection information.

---
_Source: https://npm.io/package/artefact-store · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
