{"version":3,"sources":["jsdelivr-header.js","/npm/@httptoolkit/subscriptions-transport-ws@0.11.2/src/client.ts"],"names":[],"mappings":"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","file":"/npm/@httptoolkit/subscriptions-transport-ws@0.11.2/dist/client.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/@httptoolkit/subscriptions-transport-ws@0.11.2/dist/client.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","declare let window: any;\nconst _global = typeof global !== 'undefined' ? global : (typeof window !== 'undefined' ? window : {});\nconst NativeWebSocket = _global.WebSocket || _global.MozWebSocket;\n\nimport * as Backoff from 'backo2';\nimport { default as EventEmitterType, EventEmitter, ListenerFn } from 'eventemitter3';\nimport isString from './utils/is-string';\nimport isObject from './utils/is-object';\nimport { ExecutionResult } from 'graphql/execution/execute';\nimport { print } from 'graphql/language/printer';\nimport { DocumentNode } from 'graphql/language/ast';\nimport { getOperationAST } from 'graphql/utilities/getOperationAST';\nimport $$observable from 'symbol-observable';\n\nimport { GRAPHQL_WS } from './protocol';\nimport { MIN_WS_TIMEOUT, WS_TIMEOUT } from './defaults';\nimport MessageTypes from './message-types';\n\nexport interface Observer<T> {\n  next?: (value: T) => void;\n  error?: (error: Error) => void;\n  complete?: () => void;\n}\n\nexport interface Observable<T> {\n  subscribe(observer: Observer<T>): {\n    unsubscribe: () => void;\n  };\n}\n\nexport interface OperationOptions {\n  query?: string | DocumentNode;\n  variables?: Object;\n  operationName?: string;\n  [key: string]: any;\n}\n\nexport type FormatedError = Error & {\n  originalError?: any;\n};\n\nexport interface Operation {\n  options: OperationOptions;\n  handler: (error: Error[], result?: any) => void;\n}\n\nexport interface Operations {\n  [id: string]: Operation;\n}\n\nexport interface Middleware {\n  applyMiddleware(options: OperationOptions, next: Function): void;\n}\n\nexport type ConnectionParams = {\n  [paramName: string]: any,\n};\n\nexport type ConnectionParamsOptions = ConnectionParams | Function | Promise<ConnectionParams>;\n\nexport interface ClientOptions {\n  connectionParams?: ConnectionParamsOptions;\n  minTimeout?: number;\n  timeout?: number;\n  reconnect?: boolean;\n  reconnectionAttempts?: number;\n  connectionCallback?: (error: Error[], result?: any) => void;\n  lazy?: boolean;\n  inactivityTimeout?: number;\n  wsOptionArguments?: any[];\n}\n\nexport class SubscriptionClient {\n  public client: any;\n  public operations: Operations;\n  private url: string;\n  private nextOperationId: number;\n  private connectionParams: Function;\n  private minWsTimeout: number;\n  private wsTimeout: number;\n  private unsentMessagesQueue: Array<any>; // queued messages while websocket is opening.\n  private reconnect: boolean;\n  private reconnecting: boolean;\n  private reconnectionAttempts: number;\n  private backoff: any;\n  private connectionCallback: any;\n  private eventEmitter: EventEmitterType;\n  private lazy: boolean;\n  private inactivityTimeout: number;\n  private inactivityTimeoutId: any;\n  private closedByUser: boolean;\n  private wsImpl: any;\n  private wsProtocols: string | string[];\n  private wasKeepAliveReceived: boolean;\n  private tryReconnectTimeoutId: any;\n  private checkConnectionIntervalId: any;\n  private maxConnectTimeoutId: any;\n  private middlewares: Middleware[];\n  private maxConnectTimeGenerator: any;\n  private wsOptionArguments: any[];\n\n  constructor(\n    url: string,\n    options?: ClientOptions,\n    webSocketImpl?: any,\n    webSocketProtocols?: string | string[],\n  ) {\n    const {\n      connectionCallback = undefined,\n      connectionParams = {},\n      minTimeout = MIN_WS_TIMEOUT,\n      timeout = WS_TIMEOUT,\n      reconnect = false,\n      reconnectionAttempts = Infinity,\n      lazy = false,\n      inactivityTimeout = 0,\n      wsOptionArguments = [],\n    } = (options || {});\n\n    this.wsImpl = webSocketImpl || NativeWebSocket;\n    if (!this.wsImpl) {\n      throw new Error('Unable to find native implementation, or alternative implementation for WebSocket!');\n    }\n\n    this.wsProtocols = webSocketProtocols || GRAPHQL_WS;\n    this.connectionCallback = connectionCallback;\n    this.url = url;\n    this.operations = {};\n    this.nextOperationId = 0;\n    this.minWsTimeout = minTimeout;\n    this.wsTimeout = timeout;\n    this.unsentMessagesQueue = [];\n    this.reconnect = reconnect;\n    this.reconnecting = false;\n    this.reconnectionAttempts = reconnectionAttempts;\n    this.lazy = !!lazy;\n    this.inactivityTimeout = inactivityTimeout;\n    this.closedByUser = false;\n    this.backoff = new Backoff({ jitter: 0.5 });\n    this.eventEmitter = new EventEmitter();\n    this.middlewares = [];\n    this.client = null;\n    this.maxConnectTimeGenerator = this.createMaxConnectTimeGenerator();\n    this.connectionParams = this.getConnectionParams(connectionParams);\n    this.wsOptionArguments = wsOptionArguments;\n\n    if (!this.lazy) {\n      this.connect();\n    }\n  }\n\n  public get status() {\n    if (this.client === null) {\n      return this.wsImpl.CLOSED;\n    }\n\n    return this.client.readyState;\n  }\n\n  public close(isForced = true, closedByUser = true) {\n    this.clearInactivityTimeout();\n    if (this.client !== null) {\n      this.closedByUser = closedByUser;\n\n      if (isForced) {\n        this.clearCheckConnectionInterval();\n        this.clearMaxConnectTimeout();\n        this.clearTryReconnectTimeout();\n        this.unsubscribeAll();\n        this.sendMessage(undefined, MessageTypes.GQL_CONNECTION_TERMINATE, null);\n      }\n\n      this.client.close();\n      this.client.onopen = null;\n      this.client.onclose = null;\n      this.client.onmessage = null;\n\n      // Ignore errors after close - without this uncaught 'error' events can crash node\n      this.client.onerror = () => { /* No-op */ };\n\n      this.client = null;\n      this.eventEmitter.emit('disconnected');\n\n      if (!isForced) {\n        this.tryReconnect();\n      }\n    }\n  }\n\n  public request(request: OperationOptions): Observable<ExecutionResult> {\n    const getObserver = this.getObserver.bind(this);\n    const executeOperation = this.executeOperation.bind(this);\n    const unsubscribe = this.unsubscribe.bind(this);\n\n    let opId: string;\n\n    this.clearInactivityTimeout();\n\n    return {\n      [$$observable]() {\n        return this;\n      },\n      subscribe(\n        observerOrNext: ((Observer<ExecutionResult>) | ((v: ExecutionResult) => void)),\n        onError?: (error: Error) => void,\n        onComplete?: () => void,\n      ) {\n        const observer = getObserver(observerOrNext, onError, onComplete);\n\n        opId = executeOperation(request, (error: Error[], result: any) => {\n          if ( error === null && result === null ) {\n            if ( observer.complete ) {\n              observer.complete();\n            }\n          } else if (error) {\n            if ( observer.error ) {\n              observer.error(error[0]);\n            }\n          } else {\n            if ( observer.next ) {\n              observer.next(result);\n            }\n          }\n        });\n\n        return {\n          unsubscribe: () => {\n            if ( opId ) {\n              unsubscribe(opId);\n              opId = null;\n            }\n          },\n        };\n      },\n    };\n  }\n\n  public on(eventName: string, callback: ListenerFn, context?: any): Function {\n    const handler = this.eventEmitter.on(eventName, callback, context);\n\n    return () => {\n      handler.off(eventName, callback, context);\n    };\n  }\n\n  public onConnected(callback: ListenerFn, context?: any): Function {\n    return this.on('connected', callback, context);\n  }\n\n  public onConnecting(callback: ListenerFn, context?: any): Function {\n    return this.on('connecting', callback, context);\n  }\n\n  public onDisconnected(callback: ListenerFn, context?: any): Function {\n    return this.on('disconnected', callback, context);\n  }\n\n  public onReconnected(callback: ListenerFn, context?: any): Function {\n    return this.on('reconnected', callback, context);\n  }\n\n  public onReconnecting(callback: ListenerFn, context?: any): Function {\n    return this.on('reconnecting', callback, context);\n  }\n\n  public onError(callback: ListenerFn, context?: any): Function {\n    return this.on('error', callback, context);\n  }\n\n  public unsubscribeAll() {\n    Object.keys(this.operations).forEach( subId => {\n      this.unsubscribe(subId);\n    });\n  }\n\n  public applyMiddlewares(options: OperationOptions): Promise<OperationOptions> {\n    return new Promise((resolve, reject) => {\n      const queue = (funcs: Middleware[], scope: any) => {\n        const next = (error?: any) => {\n          if (error) {\n            reject(error);\n          } else {\n            if (funcs.length > 0) {\n              const f = funcs.shift();\n              if (f) {\n                f.applyMiddleware.apply(scope, [options, next]);\n              }\n            } else {\n              resolve(options);\n            }\n          }\n        };\n        next();\n      };\n\n      queue([...this.middlewares], this);\n    });\n  }\n\n  public use(middlewares: Middleware[]): SubscriptionClient {\n    middlewares.map((middleware) => {\n      if (typeof middleware.applyMiddleware === 'function') {\n        this.middlewares.push(middleware);\n      } else {\n        throw new Error('Middleware must implement the applyMiddleware function.');\n      }\n    });\n\n    return this;\n  }\n\n  private getConnectionParams(connectionParams: ConnectionParamsOptions): Function {\n    return (): Promise<ConnectionParams> => new Promise((resolve, reject) => {\n      if (typeof connectionParams === 'function') {\n        try {\n          return resolve(connectionParams.call(null));\n        } catch (error) {\n          return reject(error);\n        }\n      }\n\n      resolve(connectionParams);\n    });\n  }\n\n  private executeOperation(options: OperationOptions, handler: (error: Error[], result?: any) => void): string {\n    if (this.client === null) {\n      this.connect();\n    }\n\n    const opId = this.generateOperationId();\n    this.operations[opId] = { options: options, handler };\n\n    this.applyMiddlewares(options)\n      .then(processedOptions => {\n        this.checkOperationOptions(processedOptions, handler);\n        if (this.operations[opId]) {\n          this.operations[opId] = { options: processedOptions, handler };\n          this.sendMessage(opId, MessageTypes.GQL_START, processedOptions);\n        }\n      })\n      .catch(error => {\n        this.unsubscribe(opId);\n        handler(this.formatErrors(error));\n      });\n\n    return opId;\n  }\n\n  private getObserver<T>(\n    observerOrNext: ((Observer<T>) | ((v: T) => void)),\n    error?: (e: Error) => void,\n    complete?: () => void,\n  ) {\n    if ( typeof observerOrNext === 'function' ) {\n      return {\n        next: (v: T) => observerOrNext(v),\n        error: (e: Error) => error && error(e),\n        complete: () => complete && complete(),\n      };\n    }\n\n    return observerOrNext;\n  }\n\n  private createMaxConnectTimeGenerator() {\n    const minValue = this.minWsTimeout;\n    const maxValue = this.wsTimeout;\n\n    return new Backoff({\n      min: minValue,\n      max: maxValue,\n      factor: 1.2,\n    });\n  }\n\n  private clearCheckConnectionInterval() {\n    if (this.checkConnectionIntervalId) {\n      clearInterval(this.checkConnectionIntervalId);\n      this.checkConnectionIntervalId = null;\n    }\n  }\n\n  private clearMaxConnectTimeout() {\n    if (this.maxConnectTimeoutId) {\n      clearTimeout(this.maxConnectTimeoutId);\n      this.maxConnectTimeoutId = null;\n    }\n    }\n\n  private clearTryReconnectTimeout() {\n    if (this.tryReconnectTimeoutId) {\n      clearTimeout(this.tryReconnectTimeoutId);\n      this.tryReconnectTimeoutId = null;\n    }\n  }\n\n  private clearInactivityTimeout() {\n    if (this.inactivityTimeoutId) {\n      clearTimeout(this.inactivityTimeoutId);\n      this.inactivityTimeoutId = null;\n    }\n  }\n\n  private setInactivityTimeout() {\n    if (this.inactivityTimeout > 0 && Object.keys(this.operations).length === 0) {\n      this.inactivityTimeoutId = setTimeout(() => {\n        if (Object.keys(this.operations).length === 0) {\n          this.close();\n        }\n      }, this.inactivityTimeout);\n    }\n  }\n\n  private checkOperationOptions(options: OperationOptions, handler: (error: Error[], result?: any) => void) {\n    const { query, variables, operationName } = options;\n\n    if (!query) {\n      throw new Error('Must provide a query.');\n    }\n\n    if (!handler) {\n      throw new Error('Must provide an handler.');\n    }\n\n    if (\n      ( !isString(query) && !getOperationAST(query, operationName)) ||\n      ( operationName && !isString(operationName)) ||\n      ( variables && !isObject(variables))\n    ) {\n      throw new Error('Incorrect option types. query must be a string or a document,' +\n        '`operationName` must be a string, and `variables` must be an object.');\n    }\n  }\n\n  private buildMessage(id: string, type: string, payload: any) {\n    const payloadToReturn = payload && payload.query ?\n      {\n        ...payload,\n        query: typeof payload.query === 'string' ? payload.query : print(payload.query),\n      } :\n      payload;\n\n    return {\n      id,\n      type,\n      payload: payloadToReturn,\n    };\n  }\n\n  // ensure we have an array of errors\n  private formatErrors(errors: any): FormatedError[] {\n    if (Array.isArray(errors)) {\n      return errors;\n    }\n\n    // TODO  we should not pass ValidationError to callback in the future.\n    // ValidationError\n    if (errors && errors.errors) {\n      return this.formatErrors(errors.errors);\n    }\n\n    if (errors && errors.message) {\n      return [errors];\n    }\n\n    return [{\n      name: 'FormatedError',\n      message: 'Unknown error',\n      originalError: errors,\n    }];\n  }\n\n  private sendMessage(id: string, type: string, payload: any) {\n    this.sendMessageRaw(this.buildMessage(id, type, payload));\n  }\n\n  // send message, or queue it if connection is not open\n  private sendMessageRaw(message: Object) {\n    switch (this.status) {\n      case this.wsImpl.OPEN:\n        let serializedMessage: string = JSON.stringify(message);\n        try {\n          JSON.parse(serializedMessage);\n        } catch (e) {\n          this.eventEmitter.emit('error', new Error(`Message must be JSON-serializable. Got: ${message}`));\n        }\n\n        this.client.send(serializedMessage);\n        break;\n      case this.wsImpl.CONNECTING:\n        this.unsentMessagesQueue.push(message);\n\n        break;\n      default:\n        if (!this.reconnecting) {\n          this.eventEmitter.emit('error', new Error('A message was not sent because socket is not connected, is closing or ' +\n            'is already closed. Message was: ' + JSON.stringify(message)));\n        }\n    }\n  }\n\n  private generateOperationId(): string {\n    return String(++this.nextOperationId);\n  }\n\n  private tryReconnect() {\n    if (!this.reconnect || this.backoff.attempts >= this.reconnectionAttempts) {\n      return;\n    }\n\n    if (!this.reconnecting) {\n      Object.keys(this.operations).forEach((key) => {\n        this.unsentMessagesQueue.push(\n          this.buildMessage(key, MessageTypes.GQL_START, this.operations[key].options),\n        );\n      });\n      this.reconnecting = true;\n    }\n\n    this.clearTryReconnectTimeout();\n\n    const delay = this.backoff.duration();\n    this.tryReconnectTimeoutId = setTimeout(() => {\n      this.connect();\n    }, delay);\n  }\n\n  private flushUnsentMessagesQueue() {\n    this.unsentMessagesQueue.forEach((message) => {\n      this.sendMessageRaw(message);\n    });\n    this.unsentMessagesQueue = [];\n  }\n\n  private checkConnection() {\n    if (this.wasKeepAliveReceived) {\n      this.wasKeepAliveReceived = false;\n      return;\n    }\n\n    if (!this.reconnecting) {\n      this.close(false, true);\n    }\n  }\n\n  private checkMaxConnectTimeout() {\n    this.clearMaxConnectTimeout();\n\n    // Max timeout trying to connect\n    this.maxConnectTimeoutId = setTimeout(() => {\n      if (this.status !== this.wsImpl.OPEN) {\n        this.reconnecting = true;\n        this.close(false, true);\n      }\n    }, this.maxConnectTimeGenerator.duration());\n  }\n\n  private connect() {\n    this.client = new this.wsImpl(this.url, this.wsProtocols, ...this.wsOptionArguments);\n\n    this.checkMaxConnectTimeout();\n\n    this.client.onopen = async () => {\n      if (this.status === this.wsImpl.OPEN) {\n        this.clearMaxConnectTimeout();\n        this.closedByUser = false;\n        this.eventEmitter.emit(this.reconnecting ? 'reconnecting' : 'connecting');\n\n        try {\n          const connectionParams: ConnectionParams = await this.connectionParams();\n\n          // Send CONNECTION_INIT message, no need to wait for connection to success (reduce roundtrips)\n          this.sendMessage(undefined, MessageTypes.GQL_CONNECTION_INIT, connectionParams);\n          this.flushUnsentMessagesQueue();\n        } catch (error) {\n          this.sendMessage(undefined, MessageTypes.GQL_CONNECTION_ERROR, error);\n          this.flushUnsentMessagesQueue();\n        }\n      }\n    };\n\n    this.client.onclose = () => {\n      if (!this.closedByUser) {\n        this.close(false, false);\n      }\n    };\n\n    this.client.onerror = (err: Error) => {\n      // Capture and ignore errors to prevent unhandled exceptions, wait for\n      // onclose to fire before attempting a reconnect.\n      this.eventEmitter.emit('error', err);\n    };\n\n    this.client.onmessage = ({ data }: {data: string | Buffer}) => {\n      this.processReceivedData(data.toString());\n    };\n  }\n\n  private processReceivedData(receivedData: any) {\n    let parsedMessage: any;\n    let opId: string;\n\n    try {\n      parsedMessage = JSON.parse(receivedData);\n      opId = parsedMessage.id;\n    } catch (e) {\n      throw new Error(`Message must be JSON-parseable. Got: ${receivedData}`);\n    }\n\n    if (\n      [ MessageTypes.GQL_DATA,\n        MessageTypes.GQL_COMPLETE,\n        MessageTypes.GQL_ERROR,\n      ].indexOf(parsedMessage.type) !== -1 && !this.operations[opId]\n    ) {\n      this.unsubscribe(opId);\n\n      return;\n    }\n\n    switch (parsedMessage.type) {\n      case MessageTypes.GQL_CONNECTION_ERROR:\n        if (this.connectionCallback) {\n          this.connectionCallback(parsedMessage.payload);\n        }\n        break;\n\n      case MessageTypes.GQL_CONNECTION_ACK:\n        this.eventEmitter.emit(this.reconnecting ? 'reconnected' : 'connected', parsedMessage.payload);\n        this.reconnecting = false;\n        this.backoff.reset();\n        this.maxConnectTimeGenerator.reset();\n\n        if (this.connectionCallback) {\n          this.connectionCallback();\n        }\n        break;\n\n      case MessageTypes.GQL_COMPLETE:\n        const handler = this.operations[opId].handler;\n        delete this.operations[opId];\n        handler.call(this, null, null);\n        break;\n\n      case MessageTypes.GQL_ERROR:\n        this.operations[opId].handler(this.formatErrors(parsedMessage.payload), null);\n        delete this.operations[opId];\n        break;\n\n      case MessageTypes.GQL_DATA:\n        const parsedPayload = !parsedMessage.payload.errors ?\n          parsedMessage.payload : {...parsedMessage.payload, errors: this.formatErrors(parsedMessage.payload.errors)};\n        this.operations[opId].handler(null, parsedPayload);\n        break;\n\n      case MessageTypes.GQL_CONNECTION_KEEP_ALIVE:\n        const firstKA = typeof this.wasKeepAliveReceived === 'undefined';\n        this.wasKeepAliveReceived = true;\n\n        if (firstKA) {\n          this.checkConnection();\n        }\n\n        if (this.checkConnectionIntervalId) {\n          clearInterval(this.checkConnectionIntervalId);\n          this.checkConnection();\n        }\n        this.checkConnectionIntervalId = setInterval(this.checkConnection.bind(this), this.wsTimeout);\n        break;\n\n      default:\n        throw new Error('Invalid message type!');\n    }\n  }\n\n  private unsubscribe(opId: string) {\n    if (this.operations[opId]) {\n      delete this.operations[opId];\n      this.setInactivityTimeout();\n      this.sendMessage(opId, MessageTypes.GQL_STOP, undefined);\n    }\n  }\n}\n"]}