export class FileChangeNotificationService { public rpc: RPC = new RPC public events: Leaf.EventEmitter<"change"> = new Leaf.EventEmitter() public connector = new ConnectionKeepProcedure(this.rpc) constructor(public path: string) { this.connector.start(path) this.rpc.remoteEvents.listenBy(this, "change", () => { this.events.emit("change") }) } } class RPC extends Leaf.RPCComposer { } class ConnectionKeepProcedure extends Leaf.States { constructor(public rpc: Leaf.RPCComposer) { super() this.debug() } protected data: { connection: WebSocket } public path: string = window.location.toString().replace("http", "ws") start(path?: string) { if (path) { this.path = path } if (this.state === "void") { this.setState("connecting") } } atConnecting(stale) { this.data.connection = new WebSocket(this.path) let openHandler = () => { this.data.connection.removeEventListener("close", closeHandler) this.setState("setup") } let closeHandler = () => { if (stale()) return this.data.connection.removeEventListener("open", openHandler) this.data.connection.removeEventListener("close", closeHandler) this.setState("waitReconnect") } this.data.connection.addEventListener("open", openHandler) this.data.connection.addEventListener("close", closeHandler) } atSetup(stale) { let conn = new Leaf.RPCBrowserWebSocketConnection(this.data.connection) this.rpc.setConnection(conn) this.setState("working") } atWorking(stale) { let closeHandler = () => { if (stale()) return this.data.connection.removeEventListener("close", closeHandler) this.setState("close") } this.data.connection.addEventListener("close", closeHandler) } atClose(stale) { this.setState("waitReconnect") } atWaitReconnect(stale) { setTimeout(() => { if (stale()) return this.setState("connecting") }, this.waitInterval) } public waitInterval: number = 1000 }