UNPKG

6.84 kBTypeScriptView Raw
1type FutureResolveFunction<T> = (err: Error, val: T) => void;
2type FutureOrFutureArray = Future<any> | Array<Future<any>>;
3
4// In the future we can use this to extend the type of FutureObject if typescript
5// support for dynamic types improves
6// https://stackoverflow.com/questions/44323441/changing-property-name-in-typescript-mapped-type
7// type FutureObjectFunctions<O> = {[K in keyof O]: O[K] extends ((...args: infer P) => infer R) ?
8// (...args: P) => Future<R> : never};
9//
10// type FutureObjectProperties<O> = {[K in keyof O]: O[K] extends (...args: any[]) => any ? never: O[K]};
11
12declare global {
13 type FutureObject<T> = T & any;
14 type FutureFunction<T> = (...args: any[]) => Future<T>;
15
16 interface Function {
17 /**
18 * Returns a future-function which, when run, starts running the target
19 * function and returns a future for the result.
20 *
21 * Example usage:
22 * var funcy = function(arg) {
23 * return arg+1;
24 * }.future();
25 *
26 * funcy(1).wait(); // returns 2
27 */
28 future<T = any>(detach?: boolean): FutureFunction<T>;
29 }
30}
31
32interface FutureConstructor {
33 new <T> (): Future<T>;
34 /**
35 * Wrap a node-style async function to return a future in place of using a callback.
36 * A node-style async function is usually in the form (...args: any, cb: (err?: Error, ...cbArgs: any) => any) => any
37 *
38 * If a single function is passed, a future-returning function is created. If an object is passed a
39 * new object is returned with all functions wrapped.
40 *
41 * The value that is returned from the invocation of the underlying function is assigned to the
42 * property `_` on the future. This is useful for functions like `execFile` which take a callback,
43 * but also return meaningful information.
44 *
45 * @param fnOrObject - the function or object to wrap
46 * @param multi - indicates that this callback will return more than 1 argument after `err`. For example,
47 * `child_process.exec()` returns [err, stdout, stderr]
48 * @param suffix - appends a string to every method that was overridden.
49 * If you passed an object. Default is 'Future'.
50 *
51 * Example usage: Future.wrap(asyncFunction)(arg1).wait()
52 */
53 wrap<T>(fnOrObject: (...args: any[]) => T, multi?: boolean, suffix?: string): FutureFunction<T>;
54 wrap<O extends object>(fnOrObject: O, multi?: boolean, suffix?: string): FutureObject<O>;
55 // wrap<O = object, T = FutureObject>(fnOrObject: O, multi?: boolean, suffix?: string): FutureObject & FunctionProperties<O>;
56
57 /**
58 * Invoke a function(s) that will be run in its own fiber context and return a future to its return
59 * value.
60 *
61 * @description Run a function(s) in a future context, and return a future to their return value. This is useful
62 * for instances where you want a closure to be able to `.wait()`. This also lets you wait for
63 * mulitple parallel opertions to run.
64 *
65 * Example:
66 * Future.task(function() {
67 * // You can safely `wait` on stuff here
68 * }).detach();
69 */
70 task<T>(fn: (...args: any[]) => T): Future<T>;
71 task<T = any>(fn1: Function, fn2: Function, ...fns: Function[]): Future<T[]>;
72
73 /**
74 * Wait on a series of futures and then return. If the futures throw an exception this function
75 * /won't/ throw it back. You can get the value of the future by calling get() on it directly. If
76 * you want to wait on a single future you're better off calling future.wait() on the instance.
77 *
78 * Example usage: Future.wait(aFuture, anotherFuture)
79 */
80 wait(...futures: FutureOrFutureArray[]): void;
81
82 /**
83 * Support for converting a Future to and from ES6 Promises.
84 * @see Future#promise
85 */
86 fromPromise<R>(promise: Promise<R>): Future<R>;
87}
88
89interface Future<T> {
90 /**
91 * Return the value of this future. If the future hasn't resolved yet this will throw an error.
92 */
93 get(): T;
94
95 /**
96 * Differs from its functional counterpart in that it actually resolves the future. Thus if the
97 * future threw, future.wait() will throw.
98 *
99 * @see get
100 */
101 wait(): T;
102
103 /**
104 * Mark this future as returned. All pending callbacks will be invoked immediately.
105 *
106 * value - the value to return when get() or wait() is called.
107 *
108 * Example usage: aFuture.return(value)
109 */
110 return<T>(value?: T): void;
111
112 /**
113 * Throw from this future as returned. All pending callbacks will be invoked immediately.
114 * Note that execution will continue normally after running this method,
115 * so make sure you exit appropriately after running throw()
116 *
117 * error - the error to throw when get() or wait() is called.
118 *
119 * Example usage: aFuture.throw(new Error("Something borked"))
120 */
121 throw(err: Error): void;
122
123 /**
124 * "detach" this future. Basically this is useful if you want to run a task in a future, you
125 * aren't interested in its return value, but if it throws you don't want the exception to be
126 * lost. If this fiber throws, an exception will be thrown to the event loop and node will
127 * probably fall down.
128 */
129 detach(): void;
130
131 /**
132 * Returns whether or not this future has resolved yet.
133 */
134 isResolved(): boolean;
135
136 /**
137 * Returns a node-style function which will mark this future as resolved when called.
138 *
139 * Example usage:
140 * var errback = aFuture.resolver();
141 * asyncFunction(arg1, arg2, etc, errback)
142 * var result = aFuture.wait();
143 */
144 resolver(): FutureResolveFunction<T>;
145
146 /**
147 * Waits for this future to resolve and then invokes a callback.
148 *
149 * If only one argument is passed it is a standard function(err, val){} errback.
150 *
151 * If two arguments are passed, the first argument is a future which will be thrown to in the case
152 * of error, and the second is a function(val){} callback.
153 */
154 resolve(errback: FutureResolveFunction<T>): this;
155 resolve(future: Future<any>, callback: (val: T) => void): this;
156
157 /**
158 * Resolve only in the case of success
159 */
160 resolveSuccess(cb: (val: T) => void): this;
161
162 /**
163 * Propogate results to another future.
164 *
165 * Example usage: future1.proxy(future2) // future2 gets automatically resolved with however future1 resolves
166 */
167 proxy(future: Future<T>): void;
168
169 /**
170 * Propogate only errors to an another future or array of futures.
171 */
172 proxyErrors(futures: FutureOrFutureArray): this;
173
174 /**
175 * Support for converting a Future to and from ES6 Promises.
176 * @see FutureConstructor#fromPromise
177 */
178 promise(): Promise<T>;
179}
180
181declare const Future: FutureConstructor;
182export = Future;
183
\No newline at end of file