Skip to content

Commit

Permalink
Add TypeScript type declarations
Browse files Browse the repository at this point in the history
  • Loading branch information
vweevers committed Mar 20, 2022
1 parent 9341584 commit 40bc944
Show file tree
Hide file tree
Showing 4 changed files with 230 additions and 6 deletions.
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,9 @@ Create a new host that exposes the given `db`, which must be an `abstract-level`
The optional `options` object may contain:

- `readonly` (boolean, default `false`): reject write operations like `db.put()`
- `preput` (function, default none): `function (key, val, cb) {}` called before puts
- `predel` (function, default none): `function (key, cb) {}` called before dels
- `prebatch` (function, default none): `function (batch, cb) {}` called before batches.
- `preput` (function, default none): a `function (key, val, cb) {}` to be called before `db.put()` operations
- `predel` (function, default none): a `function (key, cb) {}` to be called before `db.del()` operations
- `prebatch` (function, default none): a `function (operations, cb) {}` to be called before `db.batch()` operations.

#### `hostStream = host.createRpcStream()`

Expand All @@ -119,7 +119,7 @@ The database opens itself but (unlike other `abstract-level` implementations) ca

Create a duplex guest stream to be piped into a host stream. Until that's done, operations made on `db` are queued up in memory. Will throw if `createRpcStream()` was previously called and that stream has not (yet) closed. The optional `options` object may contain:

- `ref` (object, default `null`): an object to only keep the Node.js event loop alive while there are pending database operations. Should have a `ref()` method to be called on a new operation like `db.get()` and an `unref()` method to be called when all operations have finished (or when the database is closed). A Node.js `net` socket satisfies that interface. The `ref` option is not relevant when `ManyLevelGuest` is used in a browser environment.
- `ref` (object, default `null`): an object to only keep the Node.js event loop alive while there are pending database operations. Should have a `ref()` method to be called on a new database operation like `db.get()` and an `unref()` method to be called when all operations have finished (or when the database is closed). A Node.js `net` socket satisfies that interface. The `ref` option is not relevant when `ManyLevelGuest` is used in a browser environment (which, side note, is not officially supported yet).

#### `guestStream = db.connect()`

Expand All @@ -141,6 +141,8 @@ With [npm](https://npmjs.org) do:
npm i many-level
```

Usage from TypeScript also requires `npm install @types/readable-stream`.

## Contributing

[`Level/many-level`](https://github.com/Level/many-level) is an **OPEN Open Source Project**. This means that:
Expand Down
209 changes: 209 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
import {
AbstractLevel,
AbstractDatabaseOptions,
AbstractOpenOptions,
NodeCallback
} from 'abstract-level'

// Requires `npm install @types/readable-stream`.
import { Duplex } from 'readable-stream'

/**
* Guest database that reads and writes to the host's database.
*
* @template KDefault The default type of keys if not overridden on operations.
* @template VDefault The default type of values if not overridden on operations.
*/
export class ManyLevelGuest<KDefault = string, VDefault = string>
extends AbstractLevel<Buffer, KDefault, VDefault> {
/**
* Database constructor.
*
* @param options Options.
*/
constructor (options?: GuestDatabaseOptions<KDefault, VDefault> | undefined)

open (): Promise<void>
open (options: GuestOpenOptions): Promise<void>
open (callback: NodeCallback<void>): void
open (options: GuestOpenOptions, callback: NodeCallback<void>): void

/**
* Create a duplex guest stream to be piped into a host stream. Until that's done,
* operations made on this database are queued up in memory. Will throw if
* {@link createRpcStream()} was previously called and that stream has not (yet)
* closed.
*/
createRpcStream (options?: GuestRpcStreamOptions | undefined): Duplex

/**
* Alias to {@link createRpcStream()} for [`multileveldown`][1] API compatibility.
*
* [1]: https://github.com/Level/multileveldown
*/
connect (options?: GuestRpcStreamOptions | undefined): Duplex

/**
* Instead of talking to a host, forward all database operations to {@link db2}. This
* method is used by `rave-level` and serves a narrow use case. Which is to say, it may
* not work for anything other than `rave-level`. Among other things, it assumes that
* {@link db2} is open and that it uses the same encoding options as the guest database.
*
* @param db2 Another {@link AbstractLevel} database.
*/
forward (db2: AbstractLevel<Buffer, KDefault, VDefault>): void

/**
* Returns `true` if there are no operations pending to be sent to a host.
*/
isFlushed (): boolean
}

/**
* A host that exposes a given database.
*/
export class ManyLevelHost {
/**
* Host constructor.
*
* @param db An `abstract-level` database that supports the `'buffer'` encoding (most
* if not all do). It can also be a {@link AbstractLevel.sublevel()} which allows for
* exposing only a specific section of the database.
* @param options Host options.
*/
constructor (db: AbstractLevel<Buffer, any, any>, options?: HostOptions | undefined)

/**
* Create a duplex host stream to be piped into a guest stream. One per guest.
*/
createRpcStream (): Duplex
}

/**
* Options for the {@link ManyLevelGuest} constructor.
*/
declare interface GuestDatabaseOptions<K, V> extends AbstractDatabaseOptions<K, V> {
/**
* If true, resend operations when reconnected. If false, abort operations when
* disconnected, which means to yield an error on e.g. `db.get()`.
*
* @defaultValue `false`
*/
retry?: boolean

/**
* An {@link AbstractLevel} option that has no effect on {@link ManyLevelGuest}.
*/
createIfMissing?: boolean

/**
* An {@link AbstractLevel} option that has no effect on {@link ManyLevelGuest}.
*/
errorIfExists?: boolean
}

/**
* Options for the {@link ManyLevelGuest.open} method.
*/
declare interface GuestOpenOptions extends AbstractOpenOptions {
/**
* An {@link AbstractLevel} option that has no effect on {@link ManyLevelGuest}.
*/
createIfMissing?: boolean

/**
* An {@link AbstractLevel} option that has no effect on {@link ManyLevelGuest}.
*/
errorIfExists?: boolean
}

/**
* Options for the {@link ManyLevelGuest.createRpcStream} method.
*/
declare interface GuestRpcStreamOptions {
/**
* An object to only keep the Node.js event loop alive while there are pending database
* operations. Could be set to a Node.js `net` socket for example. Not relevant when
* {@link ManyLevelGuest} is used in a browser environment.
*/
ref?: GuestRef
}

/**
* A socket-like object with `ref()` and `unref()` methods.
*/
declare interface GuestRef {
/**
* Called when there's a new database operation like `db.get()`.
*/
ref: () => void

/**
* Called when all operations have finished (or when the database is closed).
*/
unref: () => void
}

/**
* Options for the {@link ManyLevelHost} constructor.
*/
declare interface HostOptions {
/**
* Reject write operations like `db.put()`.
*
* @defaultValue `false`
*/
readonly?: boolean

/**
* A function to be called before `db.put()` operations.
*/
preput?: (key: Buffer, value: Buffer, callback: NodeCallback<void>) => void

/**
* A function to be called before `db.del()` operations.
*/
predel?: (key: Buffer, callback: NodeCallback<void>) => void

/**
* A function to be called before `db.batch()` operations.
*/
prebatch?: (operations: HostBatchOperation[], callback: NodeCallback<void>) => void
}

declare type HostBatchOperation = HostBatchPutOperation | HostBatchDelOperation

/**
* A _put_ operation to be committed by a {@link ManyLevelHost}.
*/
declare interface HostBatchPutOperation {
/**
* Type of operation.
*/
type: 'put'

/**
* Key of the entry to be added to the database.
*/
key: Buffer

/**
* Value of the entry to be added to the database.
*/
value: Buffer
}

/**
* A _del_ operation to be committed by a {@link ManyLevelHost}.
*/
declare interface HostBatchDelOperation {
/**
* Type of operation.
*/
type: 'del'

/**
* Key of the entry to be deleted from the database.
*/
key: Buffer
}
10 changes: 8 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
"author": "Mathias Buus (@mafintosh)",
"license": "MIT",
"main": "index.js",
"types": "./index.d.ts",
"scripts": {
"test": "standard && hallmark && (nyc -s tape test/*.js | faucet) && nyc report",
"test": "standard && ts-standard *.ts && hallmark && (nyc -s tape test/*.js | faucet) && nyc report",
"coverage": "nyc report -r lcovonly",
"hallmark": "hallmark --fix",
"protobuf": "protocol-buffers schema.proto -o messages.js",
Expand All @@ -17,6 +18,7 @@
"guest.js",
"host.js",
"index.js",
"index.d.ts",
"messages.js",
"tags.js",
"CHANGELOG.md",
Expand All @@ -31,6 +33,8 @@
"protocol-buffers-encodings": "^1.1.0"
},
"devDependencies": {
"@types/readable-stream": "^2.3.13",
"@voxpelli/tsconfig": "^3.1.0",
"concat-stream": "^2.0.0",
"dependency-check": "^4.1.0",
"faucet": "^0.0.1",
Expand All @@ -41,7 +45,9 @@
"protocol-buffers": "^4.0.2",
"readable-stream": "^3.6.0",
"standard": "^16.0.3",
"tape": "^5.0.1"
"tape": "^5.0.1",
"ts-standard": "^11.0.0",
"typescript": "^4.5.5"
},
"repository": {
"type": "git",
Expand Down
7 changes: 7 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "@voxpelli/tsconfig/node12.json",
"compilerOptions": {
"checkJs": false
},
"include": ["*.ts", "types/*.ts"]
}

0 comments on commit 40bc944

Please sign in to comment.