import { callback } from "awaiting";
import { EventEmitter } from "events";
interface WaitObject extends EventEmitter {
get_state: Function;
}
export async function wait({
obj,
until,
timeout,
change_event,
}: {
obj: WaitObject;
until: Function;
timeout: number;
change_event: string;
}): Promise<any> {
function wait(cb): void {
let fail_timer: any = undefined;
function done(err, ret?): void {
obj.removeListener(change_event, f);
obj.removeListener("close", f);
if (fail_timer !== undefined) {
clearTimeout(fail_timer);
fail_timer = undefined;
}
if (cb === undefined) {
return;
}
cb(err, ret);
cb = undefined;
}
async function f() {
if (obj.get_state() === "closed") {
done(`closed - wait-until - ${change_event}`);
return;
}
let x;
try {
x = await until(obj);
} catch (err) {
done(err);
return;
}
if (x) {
done(undefined, x);
}
}
obj.on(change_event, f);
obj.on("close", f);
if (timeout) {
const fail = () => {
done("timeout");
};
fail_timer = setTimeout(fail, 1000 * timeout);
}
f();
}
return await callback(wait);
}