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