@types/fibers
Version:
TypeScript definitions for fibers
183 lines (162 loc) • 6.84 kB
TypeScript
type FutureResolveFunction<T> = (err: Error, val: T) => void;
type FutureOrFutureArray = Future<any> | Array<Future<any>>;
// In the future we can use this to extend the type of FutureObject if typescript
// support for dynamic types improves
// https://stackoverflow.com/questions/44323441/changing-property-name-in-typescript-mapped-type
// type FutureObjectFunctions<O> = {[K in keyof O]: O[K] extends ((...args: infer P) => infer R) ?
// (...args: P) => Future<R> : never};
//
// type FutureObjectProperties<O> = {[K in keyof O]: O[K] extends (...args: any[]) => any ? never: O[K]};
declare global {
type FutureObject<T> = T & any;
type FutureFunction<T> = (...args: any[]) => Future<T>;
interface Function {
/**
* Returns a future-function which, when run, starts running the target
* function and returns a future for the result.
*
* Example usage:
* var funcy = function(arg) {
* return arg+1;
* }.future();
*
* funcy(1).wait(); // returns 2
*/
future<T = any>(detach?: boolean): FutureFunction<T>;
}
}
interface FutureConstructor {
new<T>(): Future<T>;
/**
* Wrap a node-style async function to return a future in place of using a callback.
* A node-style async function is usually in the form (...args: any, cb: (err?: Error, ...cbArgs: any) => any) => any
*
* If a single function is passed, a future-returning function is created. If an object is passed a
* new object is returned with all functions wrapped.
*
* The value that is returned from the invocation of the underlying function is assigned to the
* property `_` on the future. This is useful for functions like `execFile` which take a callback,
* but also return meaningful information.
*
* @param fnOrObject - the function or object to wrap
* @param multi - indicates that this callback will return more than 1 argument after `err`. For example,
* `child_process.exec()` returns [err, stdout, stderr]
* @param suffix - appends a string to every method that was overridden.
* If you passed an object. Default is 'Future'.
*
* Example usage: Future.wrap(asyncFunction)(arg1).wait()
*/
wrap<T>(fnOrObject: (...args: any[]) => T, multi?: boolean, suffix?: string): FutureFunction<T>;
wrap<O extends object>(fnOrObject: O, multi?: boolean, suffix?: string): FutureObject<O>;
// wrap<O = object, T = FutureObject>(fnOrObject: O, multi?: boolean, suffix?: string): FutureObject & FunctionProperties<O>;
/**
* Invoke a function(s) that will be run in its own fiber context and return a future to its return
* value.
*
* @description Run a function(s) in a future context, and return a future to their return value. This is useful
* for instances where you want a closure to be able to `.wait()`. This also lets you wait for
* mulitple parallel opertions to run.
*
* Example:
* Future.task(function() {
* // You can safely `wait` on stuff here
* }).detach();
*/
task<T>(fn: (...args: any[]) => T): Future<T>;
task<T = any>(fn1: Function, fn2: Function, ...fns: Function[]): Future<T[]>;
/**
* Wait on a series of futures and then return. If the futures throw an exception this function
* /won't/ throw it back. You can get the value of the future by calling get() on it directly. If
* you want to wait on a single future you're better off calling future.wait() on the instance.
*
* Example usage: Future.wait(aFuture, anotherFuture)
*/
wait(...futures: FutureOrFutureArray[]): void;
/**
* Support for converting a Future to and from ES6 Promises.
* @see Future#promise
*/
fromPromise<R>(promise: Promise<R>): Future<R>;
}
interface Future<T> {
/**
* Return the value of this future. If the future hasn't resolved yet this will throw an error.
*/
get(): T;
/**
* Differs from its functional counterpart in that it actually resolves the future. Thus if the
* future threw, future.wait() will throw.
*
* @see get
*/
wait(): T;
/**
* Mark this future as returned. All pending callbacks will be invoked immediately.
*
* value - the value to return when get() or wait() is called.
*
* Example usage: aFuture.return(value)
*/
return<T>(value?: T): void;
/**
* Throw from this future as returned. All pending callbacks will be invoked immediately.
* Note that execution will continue normally after running this method,
* so make sure you exit appropriately after running throw()
*
* error - the error to throw when get() or wait() is called.
*
* Example usage: aFuture.throw(new Error("Something borked"))
*/
throw(err: Error): void;
/**
* "detach" this future. Basically this is useful if you want to run a task in a future, you
* aren't interested in its return value, but if it throws you don't want the exception to be
* lost. If this fiber throws, an exception will be thrown to the event loop and node will
* probably fall down.
*/
detach(): void;
/**
* Returns whether or not this future has resolved yet.
*/
isResolved(): boolean;
/**
* Returns a node-style function which will mark this future as resolved when called.
*
* Example usage:
* var errback = aFuture.resolver();
* asyncFunction(arg1, arg2, etc, errback)
* var result = aFuture.wait();
*/
resolver(): FutureResolveFunction<T>;
/**
* Waits for this future to resolve and then invokes a callback.
*
* If only one argument is passed it is a standard function(err, val){} errback.
*
* If two arguments are passed, the first argument is a future which will be thrown to in the case
* of error, and the second is a function(val){} callback.
*/
resolve(errback: FutureResolveFunction<T>): this;
resolve(future: Future<any>, callback: (val: T) => void): this;
/**
* Resolve only in the case of success
*/
resolveSuccess(cb: (val: T) => void): this;
/**
* Propogate results to another future.
*
* Example usage: future1.proxy(future2) // future2 gets automatically resolved with however future1 resolves
*/
proxy(future: Future<T>): void;
/**
* Propogate only errors to an another future or array of futures.
*/
proxyErrors(futures: FutureOrFutureArray): this;
/**
* Support for converting a Future to and from ES6 Promises.
* @see FutureConstructor#fromPromise
*/
promise(): Promise<T>;
}
declare const Future: FutureConstructor;
export = Future;