The frontend/UI server, written in JS using the MarkoJS library
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

118 lines
3.0 KiB

const EventEmitter = require("events")
const fetch = require("isomorphic-fetch")
const config = require("../config")
const compressQuery = require("graphql-query-compress")
/**
* Run a GraphQL query against the rpdata backend
*
* @param {string} query The query to run
* @param {{[x:string]: any}} variables
* @param {{operationName:string, token: string, permissions: string[]}} options
*/
function query(query, variables = {}, options = {}) {
return fetch(config.graphqlEndpoint, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": options.token ? `Bearer ${options.token}` : null,
"X-Permissions": options.permissions ? options.permissions.join(",") : null,
},
body: JSON.stringify({query: query.length > 256 ? compressQuery(query || "") : query, variables, operationName: options.operationName}),
credentials: "include",
}).then(res => {
return res.json()
}).then(json => {
if (json.errors != null && json.errors.length > 0) {
return Promise.reject(json.errors)
}
return json.data
})
}
class Subscription extends EventEmitter {
constructor(query, variables) {
super()
this.query = query
this.variables = Object.assign({}, variables)
this.websocket = null
this.verboseLogging = false
}
connect() {
const baseUrl = (window.location.protocol === 'https:' ? 'wss://' : 'ws://') + window.location.host
let id = 1
this.websocket = new WebSocket(baseUrl + config.graphqlEndpoint, "graphql-ws")
this.websocket.onopen = () => {
this.websocket.send(JSON.stringify({type: "connection_init", payload: {}}));
this.websocket.send(JSON.stringify({id: (id++).toFixed(0), type: "start", payload: {
query: this.query,
variables: this.variables,
extensions: {},
}}));
console.log("WS Open")
}
this.websocket.onmessage = (ev) => {
let data = {}
try {
data = JSON.parse(ev.data)
} catch (err) {
console.warn("Error", err, ev)
return
}
if (this.verboseLogging) {
console.log("WS Data:", data)
}
switch (data.type) {
case "connection_ack": {
this.emit("connect")
break;
}
case "connection_error": {
console.warn("WS Connection Error", data.payload.message)
this.websocket.close()
this.emit("error", new Error(data.payload.message))
break;
}
case "data": {
if (data.payload.errors != null && data.payload.errors.length > 0) {
this.emit("error", data.payload.errors)
} else {
this.emit("data", data.payload.data)
}
break;
}
}
}
this.websocket.onerror = (err) => {
console.warn("WS Error", err)
}
this.websocket.onclose = () => {
this.emit("disconnect")
}
}
disconnect() {
if (this.websocket != null) {
this.websocket.close();
}
}
}
module.exports = { query, Subscription }