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
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 }
|