@dialog-db/query
Version:
Datalog query engine inspired by Datomic
80 lines (66 loc) • 1.96 kB
text/typescript
import type { Result } from '../api.js'
import { SUSPEND, RESUME } from './constant.js'
export { SUSPEND, RESUME, Result }
export type Suspend = typeof SUSPEND
export interface Throw<Error extends globalThis.Error = globalThis.Error> {
join?: never
throw: Error | AbortError
}
export interface Join {
join(group: Wake): void
}
export type Command = Suspend | Throw<Error> | Join
export interface Task<
Ok,
Error extends globalThis.Error = never,
Command extends Suspend | Join | Throw<Error> = Suspend | Join | Throw<Error>,
> {
[Symbol.iterator](): Execution<Ok, Command>
}
export interface Execution<
Ok extends unknown,
Command extends Suspend | Join | Throw<Error>,
> {
throw(error: InferError<Command>): Step<Ok, Command>
return(ok: Ok): Step<Ok, Command>
next(): Step<Ok, Command>
[Symbol.iterator](): Execution<Ok, Command>
}
/**
* Wake handler which can be used to wake the suspended task.
*/
export interface Wake {
wake(): void
}
export type Step<
Ok extends unknown,
Command extends Suspend | Join | Throw<Error>,
> = IteratorResult<Command, Ok>
export type InferError<Command> = Command extends Throw<infer Error>
? Error
: never
/**
* Future is a type safe promise as it captures both success and error types and
* provides functionality to move from try/catch operating mode into `Result`
* based one.
*/
export interface Future<Ok extends unknown, Error extends globalThis.Error>
extends Promise<Ok> {
/**
* Returns a promise for the `Result` that captures both success or error
* cases.
*/
result(): Invocation<Result<Ok, Error>>
}
export interface AbortError extends Error {
name: 'AbortError'
reason: unknown
}
export interface Invocation<
Ok extends unknown,
Fail extends globalThis.Error = never,
> extends Future<Ok, Fail | AbortError>,
Task<Ok, Fail> {
abort(reason: unknown): void
[Symbol.iterator](): Execution<Ok, Suspend | Join | Throw<Fail>>
}