server-state-sync
Version:
State synchronization between multiple clients
95 lines (94 loc) • 3.93 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Constants_1 = require("../Constants");
class Client {
constructor(endpoint, identifier, accessToken) {
this.stateUpdateListeners = [];
this.addStateUpdateListener = (identifier, handler, properties = []) => {
this.stateUpdateListeners = this.stateUpdateListeners.filter(listener => listener.identifier !== identifier);
this.stateUpdateListeners.push({
identifier,
handler,
properties
});
};
this.removeStateUpdateListener = (identifier) => {
this.stateUpdateListeners = this.stateUpdateListeners.filter(listener => listener.identifier !== identifier);
};
this.onMessage = (event) => {
const { type, data } = JSON.parse(event.data);
switch (type) {
case Constants_1.ServerToClientMessageTypes.STATE_UPDATED:
this.onStateUpdated(data.updates);
break;
case Constants_1.ServerToClientMessageTypes.STATE_CONNECTION_ESTABLISHED:
this.state = data.state;
this._onStateConnectionEstablished(data.state);
break;
case Constants_1.ServerToClientMessageTypes.STATE_CONNECTION_ERROR:
this._onStateConnectionError(data);
break;
default:
break;
}
};
this.connectToState = (stateIdentifier) => {
return new Promise((resolve, reject) => {
this._onStateConnectionEstablished = resolve;
this._onStateConnectionError = reject;
this.sendMesage({
type: Constants_1.ClientToServerMessageTypes.CONNECT_TO_STATE,
data: {
stateIdentifier
}
});
});
};
this.updateState = (updates) => {
this.sendMesage({
type: Constants_1.ClientToServerMessageTypes.UPDATE_STATE,
data: {
updates
}
});
};
this.onConnection = () => new Promise((resolve) => {
this.socket.onopen = resolve;
});
this.onError = () => new Promise((resolve) => {
this.socket.onerror = resolve;
});
this.getState = () => this.state;
this.onStateUpdated = (updates) => {
const previousState = updates;
for (let key in updates) {
previousState[key] = this.state[key];
}
this.state = Object.assign(Object.assign({}, this.state), updates);
this.stateUpdateListeners.forEach(listener => {
if (listener.properties.length > 0) {
if (listener.properties.find(property => updates[property] !== undefined)) {
listener.handler(updates, previousState);
}
}
else {
listener.handler(updates, previousState);
}
});
};
this.sendMesage = (msg) => {
if (this.socket && this.socket.readyState === this.socket.OPEN) {
this.socket.send(JSON.stringify(msg));
}
else {
console.error('Not connected to StateSyncer');
}
};
this._onStateConnectionEstablished = (_) => { };
this._onStateConnectionError = (_) => { };
this.socket = new WebSocket(`${endpoint}?identifier=${identifier}&token=${accessToken || ''}`);
this.socket.onmessage = this.onMessage;
}
;
}
exports.default = Client;