UNPKG

@terrencecrowley/ot-js

Version:
99 lines (84 loc) 2.5 kB
import * as LogAbstract from "@terrencecrowley/logabstract"; import * as Context from "@terrencecrowley/context"; interface TestEnv { context: Context.IContext, log: LogAbstract.ILog }; import * as OT from "../lib/ottypes"; import * as OTC from "../lib/otcomposite"; import * as OTS from "../lib/otsession"; import * as OTEngine from "../lib/otserverengine"; import * as OTTestClient from "./ottestclient"; export class OTTestServer { private env: TestEnv; private engine: OTEngine.OTServerEngine; private clients: OTTestClient.OTTestClient[]; private editQueue: OTC.OTCompositeResource[]; // construct constructor(env: TestEnv) { this.env = env; this.engine = new OTEngine.OTServerEngine(env.log, "1"); this.clients = []; this.editQueue = []; } addClient(client: OTTestClient.OTTestClient): void { this.clients.push(client); client.setServer(this); } receive(edit: OTC.OTCompositeResource): void { this.editQueue.push(edit.copy()); } private findClient(uid: string): OTTestClient.OTTestClient { for (let i: number = 0; i < this.clients.length; i++) if (this.clients[i].clientID === uid) return this.clients[i]; return null; } tick(): void { // Drain the queue of received client events while (this.editQueue.length > 0) { let edit: OTC.OTCompositeResource = this.editQueue.shift(); let nResult: number = this.engine.addServer(edit); if (nResult === OTS.ESuccess) { edit = this.engine.logServer[this.engine.logServer.length-1]; for (let i: number = 0; i < this.clients.length; i++) this.clients[i].receiveRemoteAction(edit.copy()); } else { // Clock Unavailable if (nResult === OTS.EClockFailure) console.log("Clock failure for client " + edit.clientID); else if (nResult === OTS.EClockSeen) console.log("Sequence failure for client " + edit.clientID); edit.clock = nResult; let c: OTTestClient.OTTestClient = this.findClient(edit.clientID); if (c) c.receiveRemoteAction(edit.copy()); } } } drain(): void { let bCont: boolean = true; while (bCont) { // Dispatch any events from queue this.tick(); // And then give clients chance to respond. for (let i: number = 0; i < this.clients.length; i++) this.clients[i].checkForSend(); // And continue if they responded. bCont = this.editQueue.length > 0; } } toValue(): any { return this.engine.toValue(); } };