Monorepo for Aesthetic.Computer
aesthetic.computer
1import { Disposable, Event, EventEmitter } from "vscode";
2
3export interface PromiseAdapter<T, U> {
4 (
5 value: T,
6 resolve:
7 (value: U | PromiseLike<U>) => void,
8 reject:
9 (reason: any) => void
10 ): any;
11}
12
13const passthrough = (value: any, resolve: (value?: any) => void) => resolve(value);
14
15/**
16 * Return a promise that resolves with the next emitted event, or with some future
17 * event as decided by an adapter.
18 *
19 * If specified, the adapter is a function that will be called with
20 * `(event, resolve, reject)`. It will be called once per event until it resolves or
21 * rejects.
22 *
23 * The default adapter is the passthrough function `(value, resolve) => resolve(value)`.
24 *
25 * @param event the event
26 * @param adapter controls resolution of the returned promise
27 * @returns a promise that resolves or rejects as specified by the adapter
28 */
29 export function promiseFromEvent<T, U>(event: Event<T>, adapter: PromiseAdapter<T, U> = passthrough): { promise: Promise<U>; cancel: EventEmitter<void> } {
30 let subscription: Disposable;
31 let cancel = new EventEmitter<void>();
32
33 return {
34 promise: new Promise<U>((resolve, reject) => {
35 cancel.event(_ => reject('Cancelled'));
36 subscription = event((value: T) => {
37 try {
38 Promise.resolve(adapter(value, resolve, reject))
39 .catch(reject);
40 } catch (error) {
41 reject(error);
42 }
43 });
44 }).then(
45 (result: U) => {
46 subscription.dispose();
47 return result;
48 },
49 error => {
50 subscription.dispose();
51 throw error;
52 }
53 ),
54 cancel
55 };
56}