constructor (options) {
    super()
    options = options || {}
    this.proxy = options.proxy || false
    this.subdomainOffset = options.subdomainOffset || 2
    this.proxyIpHeader = options.proxyIpHeader || 'X-Forwarded-For'
    this.maxIpsCount = options.maxIpsCount || 0
    this.env = options.env || process.env.NODE_ENV || 'development'
    this.compose = options.compose || compose
    if (options.keys) this.keys = options.keys
    this.middleware = []
    this.context = Object.create(context)
    this.request = Object.create(request)
    this.response = Object.create(response)
    // util.inspect.custom support for node 6+
    /* istanbul ignore else */
    if (util.inspect.custom) {
      this[util.inspect.custom] = this.inspect
    }
    if (options.asyncLocalStorage) {
      if (options.asyncLocalStorage instanceof AsyncLocalStorage) {
        this.ctxStorage = options.asyncLocalStorage
      } else {
        this.ctxStorage = new AsyncLocalStorage()
      }
    }
  }
@param {object} [options] Application options
@param {string} [options.env='development'] Environment
@param {string[]} [options.keys] Signed cookie keys
@param {boolean} [options.proxy] Trust proxy headers
@param {number} [options.subdomainOffset] Subdomain offset
@param {string} [options.proxyIpHeader] Proxy IP header, defaults to X-Forwarded-For
@param {number} [options.maxIpsCount] Max IPs read from proxy IP header, default to 0 (means infinity)
@param {function} [options.compose] Function to handle middleware composition
@param {boolean} [options.asyncLocalStorage] Enable AsyncLocalStorage, default to false