k-l-lambda's picture
updated node_modules
4cadbaf
import {EventEmitter} from "events";
import sha1 from "sha1";
import * as diff from "diff";
export default class RemoteFile extends EventEmitter {
autoReconnect: boolean;
socket: WebSocket;
connected: boolean = false;
filePath: string;
timestamp: number;
_content: string;
constructor ({autoReconnect = false} = {}) {
super();
this.autoReconnect = autoReconnect;
}
get hash (): string {
return sha1(this._content) as string;
}
get content (): string {
return this._content;
}
set content (value: string) {
const timestamp = Date.now();
const patch = diff.createPatch(this.filePath, this._content, value);
this.socket.send(JSON.stringify({
command: "increase",
timestamp,
fromHash: this.hash,
toHash: sha1(value),
patch,
}));
this.timestamp = timestamp;
this._content = value;
}
connect (host: string, filePath: string) {
if (this.socket)
this.socket.close();
this.socket = new WebSocket(host, "editor-frontend");
this.socket.onopen = () => {
console.debug("[RemoteFile] socket open.");
this.connected = true;
this.emit("connected");
this.socket.send(JSON.stringify({ command: "bindFile", filePath }));
};
this.socket.onclose = event => {
console.debug("Synchronizer service socket closed:", event.code, event.reason);
this.connected = false;
this.emit("disconnected");
if (this.autoReconnect && event.code === 1006) {
console.log("[RemoteFile] try to reconnect...");
setTimeout(() => this.connect(host, filePath), 100);
}
};
this.socket.onmessage = event => {
const message = JSON.parse(event.data);
switch (message.command) {
case "failure":
console.warn("service failure:", message.description);
this.close();
break;
case "fullSync":
this.timestamp = message.timestamp;
this._content = message.content;
console.assert(this.hash === message.hash, "[RemoteFile] verify failed:", this.hash, message.hash);
this.emit("sync", {timestamp: this.timestamp});
break;
case "increase":
//console.log("increase:", this.hash, message);
// already consistent with remote, update timestemp only
if (this.hash === message.toHash) {
this.timestamp = Math.max(this.timestamp, message.timestamp);
break;
}
if (this.hash !== message.fromHash) {
if (message.timestamp < this.timestamp)
break;
console.warn("hash mismatched:", this.hash, message.fromHash);
this.socket.send(JSON.stringify({ command: "requestFullSync", timestamp: this.timestamp}));
}
else {
this.timestamp = message.timestamp;
this._content = diff.applyPatch(this._content, message.patch);
console.assert(this.hash === message.toHash, "[RemoteFile] verify failed:", this.hash, message.toHash);
this.emit("sync", {timestamp: this.timestamp});
}
break;
default:
console.warn("[RemoteFile] unexpected command:", message);
}
};
this.filePath = filePath;
}
close () {
this.socket.close();
}
};