UNPKG

dbm

Version:

309 lines (258 loc) 10.7 kB
import Dbm from "../../index.js"; export default class WebSocketConnection extends Dbm.core.BaseObject { _construct() { super._construct(); this._url = null; this._webSocket = null; this._intervalId = -1; this._callback_onOpenBound = this._callback_onOpen.bind(this); this._callback_onMessageBound = this._callback_onMessage.bind(this); this._callback_onMessageBound = this._callback_onMessage.bind(this); this._callback_onCloseBound = this._callback_onClose.bind(this); this._callback_onErrorBound = this._callback_onError.bind(this); this._callback_sendHeartbeatBound = this._callback_sendHeartbeat.bind(this); this.item.setValue("requests", []); this.item.setValue("status", 0); } setup(aUrl) { this._url = aUrl; this._connect(); return this; } _connect() { if(this.item.status === 0) { this._webSocket = new WebSocket(this._url); this.item.setValue("status", 2); this._webSocket.onopen = this._callback_onOpenBound; this._webSocket.onmessage = this._callback_onMessageBound; this._webSocket.onclose = this._callback_onCloseBound; this._webSocket.onerror = this._callback_onErrorBound; } } _getRequestItem() { let requestId = "graphApi/webSocketRequest" + Dbm.getInstance().getNextId(); let request = new Dbm.graphapi.webclient.WebSocketRequest(); request.item.register(requestId); request.item.setValue("status", Dbm.loading.LoadingStatus.NOT_STARTED); request.item.setValue("connection", this.item); return request.item; } _runRequest(aRequestItem) { if(this.item.status === 1) { aRequestItem.setValue("status", Dbm.loading.LoadingStatus.LOADING); this._webSocket.send(JSON.stringify(aRequestItem.requestData)); } else { let newRequests = [].concat(this.item.requests); newRequests.push(aRequestItem); this.item.setValue("requests", newRequests); } } requestRange(aSelect, aEncode) { let item = this._getRequestItem(); item.setValue("requestData", {"type": "range", "select": aSelect, "encode": aEncode, "requestId": item.id}); this._runRequest(item); return item; } requestItem(aId, aEncode) { let item = this._getRequestItem(); item.setValue("requestData", {"type": "item", "id": aId, "encode": aEncode, "requestId": item.id}); this._runRequest(item); return item; } requestData(aFunctionName, aData) { //console.log("requestData"); let item = this._getRequestItem(); item.setValue("requestData", {"type": "data", "functionName": aFunctionName, "data": aData, "requestId": item.id}); this._runRequest(item); return item; } performAction(aFunctionName, aData) { //console.log("performAction"); let item = this._getRequestItem(); item.setValue("requestData", {"type": "action", "functionName": aFunctionName, "data": aData, "requestId": item.id}); this._runRequest(item); return item; } createItem(aTypes, aVisibility = "draft", aChanges = [], aEncode = []) { let item = this._getRequestItem(); item.setValue("requestData", {"type": "admin/createObject", "types": aTypes, "visibility": aVisibility, "changes": aChanges, "encode": aEncode, "requestId": item.id}); this._runRequest(item); return item; } editItem(aId, aChanges, aEncode = []) { let item = this._getRequestItem(); item.setValue("requestData", {"type": "admin/editObject", "id": aId, "changes": aChanges, "encode": aEncode, "requestId": item.id}); this._runRequest(item); return item; } requestUrl(aUrl) { let item = this._getRequestItem(); item.setValue("requestData", {"type": "url", "url": aUrl, "requestId": item.id}); this._runRequest(item); return item; } _callback_onOpen(aEvent) { //console.log("_callback_onOpen"); if(this._intervalId === -1) { this._intervalId = setInterval(this._callback_sendHeartbeatBound, 20*1000); } } _callback_onClose(aEvent) { //console.log("_callback_onClose"); //console.log(aEvent); if(this._intervalId !== -1) { clearInterval(this._intervalId); this._intervalId = -1; } if(this._webSocket) { this._webSocket.onopen = null; this._webSocket.onmessage = null; this._webSocket.onclose = null; this._webSocket.onerror = null; this._webSocket = null; } this.item.setValue("status", 0); this._connect();; } _callback_onError(aEvent) { console.log("_callback_onError"); console.log(aEvent); //MENOTE: do nothing } _callback_sendHeartbeat() { //console.log("_callback_sendHeartbeat"); this._webSocket.send(JSON.stringify({"type": "heartbeat"})); } _connectionReady() { this.item.setValue("status", 1); let currentArray = this.item.requests; let currentArrayLength = currentArray.length; for(let i = 0; i < currentArrayLength; i++) { let currentItem = currentArray[i]; currentItem.setValue("status", Dbm.loading.LoadingStatus.LOADING); this._webSocket.send(JSON.stringify(currentItem.requestData)); } this.item.requests = []; } _callback_onMessage(aEvent) { //console.log("_callback_onMessage"); //console.log(aEvent.data); let data = JSON.parse(aEvent.data); let repository = Dbm.getInstance().repository; switch(data.type) { case "updateEncodedObject": { let item = repository.getItem(data["id"]); let decoder = repository.getItemIfExists("graphApi/decode/" + data["encoding"]); if(decoder) { decoder.controller.updateItemWithEncoding(item, data["data"]); } else { console.warn("No decoder for " + data["encoding"]); } } break; case "range/response": { let item = repository.getItem(data["requestId"]); item.setValue("items", repository.getItems(data["ids"])); item.setValue("status", Dbm.loading.LoadingStatus.LOADED); } break; case "item/response": { let item = repository.getItem(data["requestId"]); item.setValue("item", repository.getItem(data["id"])); item.setValue("status", Dbm.loading.LoadingStatus.LOADED); let currentArray = item.doneCommands; if(currentArray) { let currentArrayLength = currentArray.length; for(let i = 0; i < currentArrayLength; i++) { let currentCommand = currentArray[i]; currentCommand.perform(item, data["id"]); } } } break; case "data/response": case "action/response": { let item = repository.getItem(data["requestId"]); item.setValue("data", data["data"]); item.setValue("status", Dbm.loading.LoadingStatus.LOADED); let currentArray = item.doneCommands; if(currentArray) { let currentArrayLength = currentArray.length; for(let i = 0; i < currentArrayLength; i++) { let currentCommand = currentArray[i]; currentCommand.perform(item, data["data"]); } } } break; case "url/response": { let item = repository.getItem(data["requestId"]); if(data["id"]) { item.setValue("item", repository.getItem(data["id"])); } else { item.setValue("item", null); } item.setValue("status", Dbm.loading.LoadingStatus.LOADED); let currentArray = item.doneCommands; if(currentArray) { let currentArrayLength = currentArray.length; for(let i = 0; i < currentArrayLength; i++) { let currentCommand = currentArray[i]; currentCommand.perform(item, data["id"]); } } } break; case "currentUser/response": { let item = repository.getItem(data["requestId"]); if(data["id"]) { item.setValue("user", repository.getItem(data["id"])); } else { item.setValue("user", null); } repository.getItem("site").currentUser = item.user; item.setValue("status", Dbm.loading.LoadingStatus.LOADED); } break; case "connectionReady": { if(data["user"]) { repository.getItem("site").currentUser = repository.getItem(data["user"]); } else { repository.getItem("site").currentUser = null; } this._connectionReady(); } break; case "heartbeat/response": //MENOTE: do nothing break; default: console.warn("Unknown message type " + data.type); break; } } signIn(aToken) { let item = this._getRequestItem(); item.setValue("requestData", {"type": "user/signInWithToken", "token": aToken, "requestId": item.id}); this._runRequest(item); return item; } signOut() { let item = this._getRequestItem(); item.setValue("requestData", {"type": "user/signOut", "requestId": item.id}); this._runRequest(item); return item; } }