function create ({
  version,
  chunker,
  dechunker,
  channel,
  disableLosslessIntegers,
  useBigInt,
  serversideRouting,
  server, // server info
  log,
  observer
} = {}) {
  const createResponseHandler = protocol => {
    const responseHandler = new ResponseHandler({
      transformMetadata: protocol.transformMetadata.bind(protocol),
      enrichErrorMetadata: protocol.enrichErrorMetadata.bind(protocol),
      log,
      observer
    })

    // reset the error handler to just handle errors and forget about the handshake promise
    channel.onerror = observer.onError.bind(observer)

    // Ok, protocol running. Simply forward all messages to the dechunker
    channel.onmessage = buf => dechunker.write(buf)

    // setup dechunker to dechunk messages and forward them to the message handler
    dechunker.onmessage = buf => {
      try {
        responseHandler.handleResponse(protocol.unpack(buf))
      } catch (e) {
        return observer.onError(e)
      }
    }

    return responseHandler
  }

  return createProtocol(
    version,
    server,
    chunker,
    { disableLosslessIntegers, useBigInt },
    serversideRouting,
    createResponseHandler,
    observer.onProtocolError.bind(observer),
    log
  )
}
Creates a protocol with a given version

@param {object} config
@param {number} config.version The version of the protocol
@param {channel} config.channel The channel
@param {Chunker} config.chunker The chunker
@param {Dechunker} config.dechunker The dechunker
@param {Logger} config.log The logger
@param {ResponseHandler~Observer} config.observer Observer
@param {boolean} config.disableLosslessIntegers Disable the lossless integers
@param {boolean} packstreamConfig.useBigInt if this connection should convert all received integers to native BigInt numbers.
@param {boolean} config.serversideRouting It's using server side routing