{"version":3,"file":"index.modern.mjs","sources":["../src/index.ts"],"sourcesContent":["import {\n  Obj,\n  GqlTransport,\n  graphqlError,\n  networkError,\n  OperationContext,\n  OperationResult,\n} from '@pql/client';\nimport { Observable, SubscriptionObserver } from '@pql/observable';\n\nexport function noop() {}\n\nconst MsgTypes = {\n  GQL_CONNECTION_INIT: 'connection_init', // Client -> Server\n  GQL_CONNECTION_ACK: 'connection_ack', // Server -> Client\n  GQL_CONNECTION_ERROR: 'connection_error', // Server -> Client\n  GQL_CONNECTION_TERMINATE: 'connection_terminate', // Client -> Server\n  GQL_START: 'start', // Client -> Server\n  GQL_DATA: 'data', // Server -> Client\n  GQL_ERROR: 'error', // Server -> Client\n  GQL_COMPLETE: 'complete', // Server -> Client\n  GQL_STOP: 'stop', // Client -> Server\n};\n\ninterface SocketOptions {\n  url: string;\n  timeout?: number;\n  maxAttempts?: number;\n  headers?: { [index: string]: string };\n  checkOnline?: boolean;\n}\n\nconst defaultOpts: Partial<SocketOptions> = {\n  timeout: 1000,\n  maxAttempts: 5,\n  checkOnline: false,\n};\n\nfunction msg(type: string, payload?: any, id?: string) {\n  return {\n    type,\n    payload,\n    id,\n  };\n}\n\nfunction listen(cb: (online: boolean) => void, add = true): Function {\n  let fn = () => cb(navigator.onLine);\n  let f = (window as any)[(add ? 'add' : 'remove') + 'EventListener'];\n  ['online', 'offline'].map(ev => f(ev, fn));\n  return listen.bind(null, fn, false);\n}\n\nexport class SocketTransport implements GqlTransport {\n  private ws!: WebSocket;\n  private counter: number = 0;\n  private readonly max: number;\n  private isOpen: boolean = false;\n  private isReconnecting: boolean = false;\n  private online: boolean = true;\n  private readonly opts: SocketOptions;\n  private subscriptions: {\n    [key: string]: {\n      observer: SubscriptionObserver<OperationResult<any>>;\n      message: {\n        id: string;\n        type: string;\n        payload: any;\n      };\n      type: 'query' | 'mutation' | 'subscription';\n    };\n  } = {};\n  private lastid: number = 0;\n  private readonly unsub: Function;\n\n  constructor(opts: SocketOptions) {\n    this.opts = Object.assign(\n      defaultOpts,\n      opts,\n      typeof window === 'undefined'\n        ? {\n            watchOnline: false,\n          }\n        : {}\n    );\n    this.max = opts.maxAttempts || Infinity;\n    this.unsub = opts.checkOnline ? listen(this.onlineChange.bind(this)) : noop;\n    this.open();\n  }\n\n  private onlineChange() {\n    this.online = navigator.onLine;\n    if (!this.online && this.isOpen) {\n      this.ws.close(1000, 'closed');\n    } else if (this.isReconnecting && this.online) {\n      this.reconnect();\n    }\n  }\n\n  private onMessage(event: MessageEvent) {\n    const data: {\n      id?: string;\n      type: string;\n      payload?: null | {\n        data: null | any;\n        errors?: null | any[];\n      };\n    } = JSON.parse(event.data);\n\n    const sub = this.subscriptions[data.id!];\n\n    switch (data.type) {\n      case MsgTypes.GQL_CONNECTION_ACK: {\n        console.log('init_success, the handshake is complete');\n        break;\n      }\n      case MsgTypes.GQL_CONNECTION_ERROR: {\n        console.error('init_fail returned from WebSocket server');\n        break;\n      }\n      case MsgTypes.GQL_DATA: {\n        sub &&\n          sub.observer.next({\n            data: data.payload!.data!,\n            error: data.payload!.errors\n              ? graphqlError(data.payload!.errors!)\n              : null,\n          });\n        break;\n      }\n      case MsgTypes.GQL_COMPLETE: {\n        sub && sub.observer.complete();\n        delete this.subscriptions[data.id!];\n        break;\n      }\n      case MsgTypes.GQL_ERROR: {\n        sub && sub.observer.error(graphqlError(data.payload!.errors!));\n        break;\n      }\n    }\n  }\n\n  private open() {\n    this.ws = new WebSocket(this.opts.url, 'graphql-ws');\n\n    this.ws.onmessage = this.onMessage.bind(this);\n\n    this.ws.onopen = () => {\n      this.isOpen = true;\n      this.counter = 0;\n      this.isReconnecting = false;\n\n      const message = msg(MsgTypes.GQL_CONNECTION_INIT, this.opts.headers);\n\n      this.json(message);\n      Object.values(this.subscriptions).forEach(s => this.json(s.message));\n    };\n\n    this.ws.onclose = e => {\n      if (!this.isReconnecting) {\n        Object.values(this.subscriptions).forEach(s => {\n          if (s.type === 'mutation') {\n            s.observer.error(\n              networkError(\n                new Error(\n                  'Websocket closed' + (e.reason ? ': ' + e.reason : '.')\n                )\n              )\n            );\n            delete this.subscriptions[s.message.id];\n          }\n        });\n      }\n      if (~[0, 1, 5, 10].map(i => i + 1e3).indexOf(e.code)) {\n        this.isOpen = false;\n        this.isReconnecting = false;\n        this.flushError(e);\n      } else {\n        this.reconnect(e);\n      }\n    };\n  }\n\n  private flushError(e?: CloseEvent) {\n    Object.values(this.subscriptions).forEach(\n      ({ observer, message: { id } }) => {\n        observer.error(\n          networkError(\n            new Error(\n              'Websocket closed' + (e && e.reason ? ': ' + e.reason : '.')\n            )\n          )\n        );\n        delete this.subscriptions[id];\n      }\n    );\n  }\n\n  private reconnect(e?: CloseEvent) {\n    if (this.counter < this.max) {\n      if (!this.online) return;\n      this.counter++;\n      this.isReconnecting = true;\n      setTimeout(this.open.bind(this), this.opts.timeout);\n    } else {\n      this.flushError(e);\n    }\n  }\n\n  private json(x: any) {\n    this.ws.send(JSON.stringify(x));\n  }\n\n  execute<T = Obj, Vars = {}>(\n    ctx: OperationContext<Vars>\n  ): Observable<OperationResult<T>> {\n    return new Observable<OperationResult<T>>(observer => {\n      const id = String(this.lastid++);\n\n      const message = msg(MsgTypes.GQL_START, ctx.operation, id) as any;\n      this.subscriptions[id] = { observer, message, type: ctx.type };\n      if (this.online && this.isOpen && !this.isReconnecting)\n        this.json(message);\n      return () => {\n        this.json(msg(MsgTypes.GQL_STOP, null, id));\n      };\n    });\n  }\n\n  setHeaders(headers: Obj): void {\n    this.opts.headers = headers;\n    this.ws.close(1000, 'closed');\n    this.reconnect();\n  }\n\n  close() {\n    return Promise.resolve().then(() => {\n      this.unsub();\n\n      if (!this.isOpen) {\n        this.isReconnecting = false;\n        return;\n      }\n\n      Object.values(this.subscriptions).forEach(sub => {\n        this.json(msg(MsgTypes.GQL_STOP, void 0, sub.message.id));\n        sub.observer.complete();\n      });\n\n      this.json(msg(MsgTypes.GQL_CONNECTION_TERMINATE));\n      this.ws.close(1000, 'closed');\n    });\n  }\n}\n"],"names":["noop","MsgTypes","GQL_CONNECTION_INIT","GQL_CONNECTION_ACK","GQL_CONNECTION_ERROR","GQL_CONNECTION_TERMINATE","GQL_START","GQL_DATA","GQL_ERROR","GQL_COMPLETE","GQL_STOP","defaultOpts","timeout","maxAttempts","checkOnline","msg","type","payload","id","listen","cb","add","fn","navigator","onLine","f","window","map","ev","bind","SocketTransport","opts","Object","assign","watchOnline","max","Infinity","unsub","onlineChange","open","online","isOpen","ws","close","isReconnecting","reconnect","onMessage","event","data","JSON","parse","sub","subscriptions","console","log","error","observer","next","errors","graphqlError","complete","WebSocket","url","onmessage","onopen","counter","message","headers","json","values","forEach","s","onclose","e","networkError","Error","reason","i","indexOf","code","flushError","setTimeout","x","send","stringify","execute","ctx","Observable","String","lastid","operation","setHeaders","Promise","resolve","then"],"mappings":"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"}