class Queue Promise }> { private current?: Node; private end?: Node; private status: "waiting" | "running" = "waiting"; private _myResolve?: (v: "finished" | "stopped") => void; private _promise?: Promise<"finished" | "stopped">; append(item: T, autoRun = false) { const node = new Node(item); if (!this.current || !this.end) { this.current = this.end = node; } else { this.end.setNext(node); this.end = node; } if (autoRun) { this.startRun(); } } startRun() { if (this.status === "waiting") { this.run(); this._promise = new Promise<"finished" | "stopped">((resolve) => { this._myResolve = resolve; }); } return this._promise; } async run() { if (this.current) { this.status = "running"; const current = this.current; const self = current.getSelf(); this.current = this.current.getNext(); const res = await self.run(); current.destroy(); if (res === false) { this.status = "waiting"; this._myResolve("stopped"); this._promise = undefined; this._myResolve = undefined; } else { this.run(); } } else { this.end = undefined; this.status = "waiting"; this._myResolve("finished"); this._promise = undefined; this._myResolve = undefined; } } } class Node { private prev?: Node; private next?: Node; private self: T; constructor(self: T) { this.self = self; } getSelf() { return this.self; } setPrev(prev?: Node) { this.prev = prev; if (prev) { prev.next = this; } } setNext(next?: Node) { this.next = next; if (next) { next.prev = this; } } getPrev() { return this.prev; } getNext() { return this.next; } destroy() { if (this.prev) { this.prev.setNext(undefined); } if (this.next) { this.next.setPrev(undefined); } this.prev = undefined; this.next = undefined; this.self = undefined; } } export { Queue };