Full Code of mqttjs/MQTT.js for AI

main 280a3119d8f1 cached
133 files
535.2 KB
166.5k tokens
268 symbols
1 requests
Download .txt
Showing preview only (570K chars total). Download the full file or copy to clipboard to get everything.
Repository: mqttjs/MQTT.js
Branch: main
Commit: 280a3119d8f1
Files: 133
Total size: 535.2 KB

Directory structure:
gitextract__ue8z3qn/

├── .editorconfig
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.yml
│   │   ├── config.yml
│   │   └── feature_request.md
│   └── workflows/
│       ├── ISSUE_TEMPLATE/
│       │   ├── bug_report.yml
│       │   ├── config.yml
│       │   └── feature_request.md
│       ├── browser-tests.yml
│       ├── electron-tests.yml
│       ├── mqttjs-test.yml
│       ├── release-it.yml
│       ├── semantic-pr.yml
│       └── stale.yml
├── .gitignore
├── .prettierignore
├── .prettierrc.js
├── .release-it.json
├── CHANGELOG.OLD.md
├── CHANGELOG.md
├── CONTRIBUTING.md
├── DEVELOPMENT.md
├── LICENSE.md
├── README.md
├── benchmarks/
│   ├── bombing.js
│   └── throughputCounter.js
├── electron-test/
│   ├── .gitignore
│   ├── README
│   ├── forge.config.js
│   ├── package.json
│   ├── src/
│   │   ├── index.css
│   │   ├── index.html
│   │   ├── index.js
│   │   └── renderer.js
│   ├── test/
│   │   ├── service/
│   │   │   └── server_launcher.ts
│   │   └── specs/
│   │       └── test.e2e.ts
│   ├── tsconfig.json
│   └── wdio.conf.ts
├── esbuild.js
├── eslint.config.js
├── example.ts
├── examples/
│   ├── client/
│   │   ├── secure-client.js
│   │   ├── simple-both.js
│   │   ├── simple-publish.js
│   │   └── simple-subscribe.js
│   ├── tls client/
│   │   ├── crt.ca.cg.pem
│   │   ├── mqttclient.js
│   │   ├── tls-cert.pem
│   │   └── tls-key.pem
│   ├── vite-example/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── index.html
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── App.vue
│   │   │   ├── assets/
│   │   │   │   ├── base.css
│   │   │   │   └── main.css
│   │   │   └── main.js
│   │   └── vite.config.js
│   ├── ws/
│   │   ├── aedes_server.js
│   │   └── client.js
│   └── wss/
│       └── client_with_proxy.js
├── help/
│   ├── help.txt
│   ├── publish.txt
│   └── subscribe.txt
├── nyc.config.js
├── package.json
├── src/
│   ├── bin/
│   │   ├── mqtt.ts
│   │   ├── pub.ts
│   │   └── sub.ts
│   ├── index.ts
│   ├── lib/
│   │   ├── BufferedDuplex.ts
│   │   ├── KeepaliveManager.ts
│   │   ├── TypedEmitter.ts
│   │   ├── client.ts
│   │   ├── connect/
│   │   │   ├── ali.ts
│   │   │   ├── index.ts
│   │   │   ├── socks.ts
│   │   │   ├── tcp.ts
│   │   │   ├── tls.ts
│   │   │   ├── ws.ts
│   │   │   └── wx.ts
│   │   ├── default-message-id-provider.ts
│   │   ├── get-timer.ts
│   │   ├── handlers/
│   │   │   ├── ack.ts
│   │   │   ├── auth.ts
│   │   │   ├── connack.ts
│   │   │   ├── index.ts
│   │   │   ├── publish.ts
│   │   │   └── pubrel.ts
│   │   ├── is-browser.ts
│   │   ├── shared.ts
│   │   ├── store.ts
│   │   ├── topic-alias-recv.ts
│   │   ├── topic-alias-send.ts
│   │   ├── unique-message-id-provider.ts
│   │   └── validations.ts
│   └── mqtt.ts
├── test/
│   ├── browser/
│   │   ├── certs/
│   │   │   ├── server-cert.pem
│   │   │   └── server-key.pem
│   │   ├── test.js
│   │   └── worker.js
│   └── node/
│       ├── abstract_client.ts
│       ├── abstract_store.ts
│       ├── client.ts
│       ├── client_mqtt5.ts
│       ├── helpers/
│       │   ├── TeardownHelper.ts
│       │   ├── leaked.ts
│       │   ├── port_list.ts
│       │   ├── private-csr.pem
│       │   ├── private-key.pem
│       │   ├── public-cert.pem
│       │   ├── public-key.pem
│       │   ├── server.ts
│       │   ├── server_process.ts
│       │   ├── tls-cert.pem
│       │   ├── tls-key.pem
│       │   ├── wrong-cert.pem
│       │   ├── wrong-csr.pem
│       │   └── wrong-key.pem
│       ├── keepaliveManager.ts
│       ├── message-id-provider.ts
│       ├── mqtt.ts
│       ├── mqtt_store.ts
│       ├── secure_client.ts
│       ├── server.ts
│       ├── server_helpers_for_client_tests.ts
│       ├── socks.ts
│       ├── store.ts
│       ├── unique_message_id_provider_client.ts
│       ├── util.ts
│       └── websocket_client.ts
├── tsconfig.build.json
├── tsconfig.json
└── web-test-runner.config.mjs

================================================
FILE CONTENTS
================================================

================================================
FILE: .editorconfig
================================================
root = true

[*]
end_of_line = lf
insert_final_newline = true
charset = utf-8
indent_style = space
indent_size = 2
trim_trailing_whitespace = true


================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.yml
================================================
name: Bug report
description: Template for bug reports
title: '[Bug]: '
labels:
  - bug
body:
  - type: input
    attributes:
      label: MQTTjs Version
    validations:
      required: true
  - type: input
    attributes:
      label: Broker
      description: >-
        The broker you are using (Aedes, Mosca, mosquitto, RabbitMQ, HiveMQ
        etc...)
    validations:
      required: true
  - type: dropdown
    attributes:
      label: Environment
      options:
        - NodeJS
        - Browser
    validations:
      required: true
  - type: textarea
    attributes:
      label: Description
      description: A clear and concise description of the problem
    validations:
      required: true
  - type: textarea
    attributes:
      label: Minimal Reproduction
      description: provide steps to reproduce the problem
    validations:
      required: true
  - type: textarea
    attributes:
      label: Debug logs
      description: Provide logs to help diagnose your issue
      placeholder: >-
        On NodeJS simply run your application using `DEBUG=mqttjs*` env var, on
        browsers you should enable `verbose` level in console or you can set
        `log` option to `console.log.bind(console)`
    validations:
      required: true
  - type: markdown
    attributes:
      value: >-
        This template was generated with [Issue Forms
        Creator](https://issue-forms-creator.netlify.app)


================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
contact_links:
  - name: ❓ Ask a Question
    url: https://github.com/mqttjs/MQTT.js/discussions/new
    about: If you have any other questions, ask them here.

================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
labels: enhancement
assignees: ''

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.


================================================
FILE: .github/workflows/ISSUE_TEMPLATE/bug_report.yml
================================================
name: Bug report
description: Template for bug reports
title: '[Bug]: '
labels:
  - bug
body:
  - type: input
    attributes:
      label: MQTTjs Version
    validations:
      required: true
  - type: input
    attributes:
      label: Broker
      description: >-
        The broker you are using (Aedes, Mosca, mosquitto, RabbitMQ, HiveMQ
        etc...)
    validations:
      required: true
  - type: dropdown
    attributes:
      label: Environment
      options:
        - NodeJS
        - Browser
    validations:
      required: true
  - type: textarea
    attributes:
      label: Description
      description: A clear and concise description of the problem
    validations:
      required: true
  - type: textarea
    attributes:
      label: Minimal Reproduction
      description: provide steps to reproduce the problem
    validations:
      required: true
  - type: textarea
    attributes:
      label: Debug logs
      description: Provide logs to help diagnose your issue
      placeholder: >-
        On NodeJS simply run your application using `DEBUG=mqttjs*` env var, on
        browsers you should enable `verbose` level in console or you can set
        `log` option to `console.log.bind(console)`
    validations:
      required: true
  - type: markdown
    attributes:
      value: >-
        This template was generated with [Issue Forms
        Creator](https://issue-forms-creator.netlify.app)


================================================
FILE: .github/workflows/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
contact_links:
  - name: ❓ Ask a Question
    url: https://github.com/mqttjs/MQTT.js/discussions/new
    about: If you have any other questions, ask them here.

================================================
FILE: .github/workflows/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
labels: enhancement
assignees: ''

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.


================================================
FILE: .github/workflows/browser-tests.yml
================================================
name: Browser Tests

on:
  workflow_dispatch:      
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  browser:
    runs-on: ubuntu-latest
    container: mcr.microsoft.com/playwright:v1.57.0-noble # https://playwright.dev/docs/ci-intro#via-containers
    strategy:
      matrix:
        node-version: [22.x]
      fail-fast: false

    steps:
    - uses: actions/checkout@v6
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v6
      with:
        node-version: ${{ matrix.node-version }}
        cache: 'npm'

    - name: Install Dependencies
      run: npm ci

    - name: Test Browser
      # only run on latest node version, no reason to run on all
      timeout-minutes: 2
      env:
        HOME: /root
      run: |
        npm run unit-test:browser
  




================================================
FILE: .github/workflows/electron-tests.yml
================================================
name: Electron Tests

on:
  workflow_dispatch:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  browser:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [22.x]
      fail-fast: false

    steps:
    - uses: actions/checkout@v6
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v6
      with:
        node-version: ${{ matrix.node-version }}
        cache: 'npm'

    - name: Install Dependencies
      run: npm ci

    - name: Build MQTT.JS
      run: npm run build

    - name: Run headless test
      run: cd electron-test && npm i && xvfb-run npm run wdio


================================================
FILE: .github/workflows/mqttjs-test.yml
================================================
name: MQTT.js Tests

on:
  workflow_dispatch:
    inputs:
      logLevel:
        description: 'Debug Filter'     
        required: true
        default: 'mqttjs*'
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [22.x, 24.x]
      fail-fast: false

    steps:
    - uses: actions/checkout@v6
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v6
      with:
        node-version: ${{ matrix.node-version }}
        cache: 'npm'

    - name: Install Dependencies
      run: npm ci
    
    - name: Lint
      if: matrix.node-version == '22.x'
      # only run on latest node version, no reason to run on all
      run: |
        npm run lint

    - name: Test NodeJS
      run: npm run test:node
      timeout-minutes: 5
      env:
        CI: true
        DEBUG: "${{ runner.debug == '1' && 'mqttjs:*' || '' }}"

    # upload coverage to Codecov
    # https://app.codecov.io/gh/mqttjs/MQTT.js
    - name: Upload coverage to Codecov
      uses: codecov/codecov-action@v5
      with:
        directory: ./coverage/
        fail_ci_if_error: true
        flags: unittests
        name: codecov-mqttjs
        token: ${{ secrets.CODECOV_TOKEN }}
        verbose: true
    
    - name: Upload test results to Codecov
      if: ${{ !cancelled() }}
      uses: codecov/test-results-action@v1
      with:
        files: ./junit.xml
        fail_ci_if_error: false
        flags: unittests-results
        name: codecov-mqttjs-test-results
        token: ${{ secrets.CODECOV_TOKEN }}
        verbose: true



================================================
FILE: .github/workflows/release-it.yml
================================================
# #########################################################################
# Creates a new release using `workflow_dispatch` event trigger with `type`
# as input to describe the type of release to create
name: 'Release-it: Create a new release on demand'

on:
  workflow_dispatch:
    inputs:
      type:
        description: 'Type/Options. `major --preRelease=beta`, `--preRelease`, `major`, `patch`, `minor` or `major`'
        required: false
        default: 'patch'

jobs:
  release:
    permissions:
      contents: write
      id-token: write
    runs-on: [ubuntu-latest]
    strategy:
      matrix:
        node-version: [22.x]
    steps:
      - name: Checkout main
        uses: actions/checkout@v6
        with:
          ref: 'main'
          fetch-depth: 0 # fetch all commits history to create the changelog
          token: ${{ secrets.GH_TOKEN }}

      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v6
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'npm'

      - name: Upgrade npm for OIDC support (requires npm >= 11.5.1)
        run: npm install -g npm@latest

      - name: Install dependencies
        run: npm ci
      
      - name: Initialize Git user
        run: |
          git config --global user.email "${{ github.actor }}@users.noreply.github.com }}"
          git config --global user.name "${{ github.actor }}"
      
      - name: Initialize NPM config
        run: |
          npm config set //registry.npmjs.org/:_authToken $NPM_TOKEN
        env:
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

      - name: Make the release
        env:
          GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 
        run: |
          # When all commits since the latest major tag should be added to the changelog, use --git.tagExclude='*[-]*'
          npx release-it ${{github.event.inputs.type}} --git.tagExclude='*[-]*' --ci --verbose


================================================
FILE: .github/workflows/semantic-pr.yml
================================================
name: "Semantic PR Title"

on:
  pull_request_target:
    types:
      - opened
      - edited
      - synchronize

permissions:
  pull-requests: read

jobs:
  main:
    name: Validate PR title
    runs-on: ubuntu-latest
    steps:
      - uses: amannn/action-semantic-pull-request@v6
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


================================================
FILE: .github/workflows/stale.yml
================================================
name: Close inactive issues
on:
  schedule:
    - cron: "30 1 * * *"

jobs:
  close-stale:
    runs-on: ubuntu-latest
    permissions:
      issues: write
      pull-requests: write
    steps:
      - uses: actions/stale@v10
        with:
          days-before-issue-stale: 365
          days-before-issue-close: 14
          stale-issue-label: "stale"
          stale-issue-message: |
            This is an automated message to let you know that this issue has
            gone 365 days without any activity. In order to ensure that we work
            on issues that still matter, this issue will be closed in 14 days.

            If this issue is still important, you can simply comment with a
            "bump" to keep it open.

            Thank you for your contribution.
          close-issue-message: "This issue was automatically closed due to inactivity."
          days-before-pr-stale: -1
          days-before-pr-close: -1
          repo-token: ${{ secrets.GITHUB_TOKEN }}
          exempt-all-assignees: true
          exempt-all-milestones: true
          ascending: true
          operations-per-run: 300
          debug-only: false


================================================
FILE: .gitignore
================================================
node_modules
certs/*
[._]*.s[a-w][a-z]
[._]s[a-w][a-z]
*.un~
Session.vim
.netrwhist
*~
npm-debug.log
dist/
yarn.lock
coverage
.nyc_output
.idea/*
test/typescript/.idea/*
test/typescript/*.js
test/typescript/*.map
# VS Code stuff
**/typings/**
.vscode/
.npmrc
junit.xml

/build/

# macOS stuff
.DS_Store
.DS_Store?


================================================
FILE: .prettierignore
================================================
*.md
README.md
/types/
/examples/
/doc/
/dist/


================================================
FILE: .prettierrc.js
================================================
module.exports = {
  semi: false,
  singleQuote: true,
  useTabs: true,
  tabWidth: 4,
  endOfLine: "lf",
};


================================================
FILE: .release-it.json
================================================
{
  "$schema": "https://unpkg.com/release-it@19/schema/release-it.json",
  "github": {
    "release": true
  },
  "git": {
    "tagName": "v${version}",
    "commitMessage": "chore(release): ${version}",
    "requireBranch": "main"
  },
  "hooks": {
    "before:init": [
      "npm run test"
    ]
  },
  "npm": {
    "publish": true,
    "skipChecks": true
  },
  "plugins": {
    "@release-it/conventional-changelog": {
      "preset": "angular",
      "infile": "CHANGELOG.md"
    }
  }
}


================================================
FILE: CHANGELOG.OLD.md
================================================
# Release History

## 4.3.7

### PR

fix: regression from #1401 and allow CI test failures to break gitthub workflow (#1443)

## 4.3.6

### PR

chore: update CI

fix(browser): require buffer (#1420)

fix(types): connect function proper overloads (#1416)

## 4.3.5

### PR

fix(drain-leak): fix regression introduced in #1301 (#1401)

## 4.3.4

### PR

fix(dependency): migrate LruMap from collections to lru-cache (#1396)

## 4.3.3

### PR

fix(publish): call callback when messageId available (#1393)

fix: remove collections.js depdendency from number-allocator (#1394)

### PR

fix(dependencies): update collections (#1386)

## 4.3.2

### PR

fix(dependencies): update collections (#1386)

## 4.3.1

### PR

fix(dependencies): remove babel-eslint and snazzy (#1383)

## 4.3.0

### PR

refined topic alias support (#1301)

fix security vulnerability in ws stream (#1307)

skip TLS SNI if host is IP address (#1311)

update readme about vNext discussions (#1328)

update readme sample (#1331)

add support for ALPN TLS extension (#1332)

align onConnectCallback with specs expecting connack packet (#1333)

fix resubscribe messageId allocate twice (#1337)

rework examples to be a bit more specific (#1352)

readme typo fixed (#1353)

fix(typescript): use correct version of @types/ws (#1358)

fix(type): fix push properties types (#1359)

fix: audit dev dependencies (#1374)

fix(type): add properties type for IClientSubscribeOptions (#1378)

feat(client): auth handler for enhanced auth (#1380)

## 4.2.8

### PR

Fix ws vulnerability and typescript bug (#1292)

## 4.2.7

### PR

#1287 - Fix production vulnerabilities (#1289)

#1215 - Add missing 'duplexify' dependency (#1266)

Improve type definition for 'wsOptions' (#1256)

Improve Typescript Declaratiosn for userProperties (#1249)

#1235 - Call the end on the WebSocket stream when WebSocket close event is emitted. (#1239)

#1201 - Uncaught TypeError: net.createConnection is not a function. (#1236)

Improve Documentation for Browserify (#1224)

## v4.2.6 and Below

The release history has been documented in the GitHub releases and tags historically. 


================================================
FILE: CHANGELOG.md
================================================
# Changelog

# [5.15.0](/compare/v5.14.1...v5.15.0) (2026-02-02)


### Features

* exported topic validation functions for external use (#2036) 396e02a, closes #2036

## [5.14.1](https://github.com/mqttjs/MQTT.js/compare/v5.14.0...v5.14.1) (2025-09-04)


### Bug Fixes

* **connect/ws:** ensure proxy stream is writable ([#2024](https://github.com/mqttjs/MQTT.js/issues/2024)) ([fe45405](https://github.com/mqttjs/MQTT.js/commit/fe454056d5b54718b1b3c90611026da4c908faef)), closes [#1914](https://github.com/mqttjs/MQTT.js/issues/1914)
* isWebWorkerEnv check for Deno environment ([#2023](https://github.com/mqttjs/MQTT.js/issues/2023)) ([a6e74ad](https://github.com/mqttjs/MQTT.js/commit/a6e74add5e41cf9d2a3b62357e0c0531a128e7cd))

# [5.14.0](https://github.com/mqttjs/MQTT.js/compare/v5.13.3...v5.14.0) (2025-07-30)

## [5.13.3](https://github.com/mqttjs/MQTT.js/compare/v5.13.2...v5.13.3) (2025-07-18)

## [5.13.2](https://github.com/mqttjs/MQTT.js/compare/v5.13.1...v5.13.2) (2025-07-07)


### Bug Fixes

* move back @types/ws from dev to deps ([#2008](https://github.com/mqttjs/MQTT.js/issues/2008)) ([959b132](https://github.com/mqttjs/MQTT.js/commit/959b132a492f43902deb994d119d07f15f955390)), closes [#1991](https://github.com/mqttjs/MQTT.js/issues/1991)

## [5.13.1](https://github.com/mqttjs/MQTT.js/compare/v5.13.0...v5.13.1) (2025-06-03)

# [5.13.0](https://github.com/mqttjs/MQTT.js/compare/v5.12.1...v5.13.0) (2025-05-09)


### Features

* add `subscribeBatchSize` option to split subscribe packets for AWS IoT Core ([#1995](https://github.com/mqttjs/MQTT.js/issues/1995)) ([6b719c8](https://github.com/mqttjs/MQTT.js/commit/6b719c8cd11397bb13f06c36b3fa5a3840befacb))

## [5.12.1](https://github.com/mqttjs/MQTT.js/compare/v5.12.0...v5.12.1) (2025-05-06)


### Bug Fixes

* add `@typescript-eslint/consistent-type-imports` rule and normalised all imports ([640cd3b](https://github.com/mqttjs/MQTT.js/commit/640cd3b9bd7d9a7d8ef59fa3fdd57a3a1c3ba345))

# [5.12.0](https://github.com/mqttjs/MQTT.js/compare/v5.11.1...v5.12.0) (2025-04-28)


### Features

* **exports:** add react-native entry point to package.json ([#1988](https://github.com/mqttjs/MQTT.js/issues/1988)) ([622d3d8](https://github.com/mqttjs/MQTT.js/commit/622d3d8e7d8149bbb2ee03a01254e0ab9bf42e6c))

## [5.11.1](https://github.com/mqttjs/MQTT.js/compare/v5.11.0...v5.11.1) (2025-04-23)


### Bug Fixes

* **deps:** removed unused 'reinterval' dependency and move two @type/ dependencies to devDependencies. ([bb8c694](https://github.com/mqttjs/MQTT.js/commit/bb8c6947edc4d85d77f13f8c06df7a979a270a7f))

# [5.11.0](https://github.com/mqttjs/MQTT.js/compare/v5.10.4...v5.11.0) (2025-04-10)


### Bug Fixes

* correct return type of `validateTopis` to include `null` ([#1979](https://github.com/mqttjs/MQTT.js/issues/1979)) ([935784a](https://github.com/mqttjs/MQTT.js/commit/935784aa8235fd9f38ac17820edf357ed7d5ab75))


### Features

* add intrinsic support for SOCKS proxies ([#1966](https://github.com/mqttjs/MQTT.js/issues/1966)) ([ee0fcce](https://github.com/mqttjs/MQTT.js/commit/ee0fcce4bd3e1af318b0144b9e0928c571c02173))

## [5.10.4](https://github.com/mqttjs/MQTT.js/compare/v5.10.3...v5.10.4) (2025-02-26)


### Bug Fixes

* **browser:** bump readable-stream@4.7.0 to fix BigInt issues ([#1963](https://github.com/mqttjs/MQTT.js/issues/1963)) ([9749891](https://github.com/mqttjs/MQTT.js/commit/9749891137c0eb57f20c13e17196bccbdec1029e))
* **browser:** prevent error stream.push() after EOF ([#1932](https://github.com/mqttjs/MQTT.js/issues/1932)) ([df2e8fe](https://github.com/mqttjs/MQTT.js/commit/df2e8febcccd4574a046887e612113a85900b86d))
* **electron-test:** webdriver session not created ([#1972](https://github.com/mqttjs/MQTT.js/issues/1972)) ([57691cf](https://github.com/mqttjs/MQTT.js/commit/57691cf9a088dee69e0dea637ae5742c6dfae833))
* move protocol "clean" after merge of parsedOptions ([#1965](https://github.com/mqttjs/MQTT.js/issues/1965)) ([1c19ca0](https://github.com/mqttjs/MQTT.js/commit/1c19ca0d0a810ee9a925d17552e9d84f70aa718b))

## [5.10.3](https://github.com/mqttjs/MQTT.js/compare/v5.10.2...v5.10.3) (2024-11-26)


### Bug Fixes

* add option to reconnect if connack has an error code ([#1948](https://github.com/mqttjs/MQTT.js/issues/1948)) ([fa19586](https://github.com/mqttjs/MQTT.js/commit/fa19586cf0482b007e136e013cf7c9a423b882eb))

## [5.10.2](https://github.com/mqttjs/MQTT.js/compare/v5.10.1...v5.10.2) (2024-11-13)


### Features

* **electron-test:** move third hosted broker to self hosted broker ([#1926](https://github.com/mqttjs/MQTT.js/issues/1926)) ([1ca3f9e](https://github.com/mqttjs/MQTT.js/commit/1ca3f9e37f6ef7fe86307e292042c6542ca35241))

## [5.10.1](https://github.com/mqttjs/MQTT.js/compare/v5.10.0...v5.10.1) (2024-08-28)


### Bug Fixes

* **browser:** handle `Blob` payloads ([#1930](https://github.com/mqttjs/MQTT.js/issues/1930)) ([86b7959](https://github.com/mqttjs/MQTT.js/commit/86b795983d86847e1da334fd0d30cbd80f92b540))

# [5.10.0](https://github.com/mqttjs/MQTT.js/compare/v5.9.1...v5.10.0) (2024-08-14)


### Bug Fixes

* **test:** close all open connections in abstract_client test ([#1917](https://github.com/mqttjs/MQTT.js/issues/1917)) ([661c30a](https://github.com/mqttjs/MQTT.js/commit/661c30aecb8d7531fc052a7770519267067840fb))
* **types:** unsubscribe options type ([#1921](https://github.com/mqttjs/MQTT.js/issues/1921)) ([18a357c](https://github.com/mqttjs/MQTT.js/commit/18a357ce98c2e7ae053afefaf7c56a0d3a8e62b7))


### Features

* add `suback` packet to subscribe callback ([#1923](https://github.com/mqttjs/MQTT.js/issues/1923)) ([93f4482](https://github.com/mqttjs/MQTT.js/commit/93f4482570b6e96d81a5466ea94c3fd7308ff31c))
* add unsubscribe ack packet to the unsubscribe callback ([#1922](https://github.com/mqttjs/MQTT.js/issues/1922)) ([8bcf304](https://github.com/mqttjs/MQTT.js/commit/8bcf3042a9133acf8d266d73bc67153a69660e05))

## [5.9.1](https://github.com/mqttjs/MQTT.js/compare/v5.9.0...v5.9.1) (2024-08-01)


### Bug Fixes

* **browser:** ensure proxy is defined ([ffc9805](https://github.com/mqttjs/MQTT.js/commit/ffc9805a51adf88bded6a1af1c0f66004e9e0f08))
* **browser:** prevent error `stream.push() after EOF` ([#1915](https://github.com/mqttjs/MQTT.js/issues/1915)) ([b5cc835](https://github.com/mqttjs/MQTT.js/commit/b5cc835fed9bd624c20d5f4f42b15c3cfa4b3fbe)), closes [#1914](https://github.com/mqttjs/MQTT.js/issues/1914)
* **test:** close open connections ([#1911](https://github.com/mqttjs/MQTT.js/issues/1911)) ([053a7be](https://github.com/mqttjs/MQTT.js/commit/053a7be91f93a0a27c63ca5ed488d9206fdec960))

# [5.9.0](https://github.com/mqttjs/MQTT.js/compare/v5.8.1...v5.9.0) (2024-07-26)


### Bug Fixes

* tets hang up ([#1906](https://github.com/mqttjs/MQTT.js/issues/1906)) ([c462530](https://github.com/mqttjs/MQTT.js/commit/c462530d2ec0b61a20cc43f188254bf2b403787a))
* **types:** add connectAsync overload signature with allowRetries ([#1909](https://github.com/mqttjs/MQTT.js/issues/1909)) ([6b278dc](https://github.com/mqttjs/MQTT.js/commit/6b278dca5a5b82b07835344f3c129ddd5b73e6e8))


### Features

* add `forceNativeWebSocket` client option ([#1910](https://github.com/mqttjs/MQTT.js/issues/1910)) ([103d172](https://github.com/mqttjs/MQTT.js/commit/103d1721d68952e536a3704a05a569c95f0a1987)), closes [#1796](https://github.com/mqttjs/MQTT.js/issues/1796) [#1895](https://github.com/mqttjs/MQTT.js/issues/1895)

## [5.8.1](https://github.com/mqttjs/MQTT.js/compare/v5.8.0...v5.8.1) (2024-07-18)


### Bug Fixes

* connect after client.end not working ([#1902](https://github.com/mqttjs/MQTT.js/issues/1902)) ([fbe5294](https://github.com/mqttjs/MQTT.js/commit/fbe52949b47378768fd325f01682a766a5965dfe))
* reschedule pings problem ([#1904](https://github.com/mqttjs/MQTT.js/issues/1904)) ([8e14d3e](https://github.com/mqttjs/MQTT.js/commit/8e14d3eac01f4fcccfc1ee657e0158d0644951ce))

# [5.8.0](https://github.com/mqttjs/MQTT.js/compare/v5.7.3...v5.8.0) (2024-07-05)


### Features

* add compatibility with txiki.js ([#1895](https://github.com/mqttjs/MQTT.js/issues/1895)) ([37b08c9](https://github.com/mqttjs/MQTT.js/commit/37b08c99fead5282e38b851ce1006f09521b038c))
* allow to pass custom timer for keepalive manager ([#1896](https://github.com/mqttjs/MQTT.js/issues/1896)) ([ee81184](https://github.com/mqttjs/MQTT.js/commit/ee811844d07365ca98721be90c4e1c2c1d8623b9))

## [5.7.3](https://github.com/mqttjs/MQTT.js/compare/v5.7.2...v5.7.3) (2024-06-26)


### Bug Fixes

* **wechat:** do not ignore path with `wx` protocol ([#1894](https://github.com/mqttjs/MQTT.js/issues/1894)) ([300c0b4](https://github.com/mqttjs/MQTT.js/commit/300c0b4dc5a37d8594a4cb1af5836c095b4d823c)), closes [#1892](https://github.com/mqttjs/MQTT.js/issues/1892)

## [5.7.2](https://github.com/mqttjs/MQTT.js/compare/v5.7.1...v5.7.2) (2024-06-19)


### Bug Fixes

* **security:** bump ws@8.17.1 and other audit issues ([#1891](https://github.com/mqttjs/MQTT.js/issues/1891)) ([096baaa](https://github.com/mqttjs/MQTT.js/commit/096baaaa882627554efd4bc9985ce8a5f2dfda5e))

## [5.7.1](https://github.com/mqttjs/MQTT.js/compare/v5.7.0...v5.7.1) (2024-06-18)


### Bug Fixes

* suback Error Codes Handling ([#1887](https://github.com/mqttjs/MQTT.js/issues/1887)) ([2a98e5e](https://github.com/mqttjs/MQTT.js/commit/2a98e5e878cad632fe86e738144688ee2b14a7dd))

# [5.7.0](https://github.com/mqttjs/MQTT.js/compare/v5.6.2...v5.7.0) (2024-05-28)


### Features

* add `unixSocket` option and `+unix` suffix support to protocol ([#1874](https://github.com/mqttjs/MQTT.js/issues/1874)) ([1004c78](https://github.com/mqttjs/MQTT.js/commit/1004c78db7d6763f21c98fa3db2f12e688ca33ff))

## [5.6.2](https://github.com/mqttjs/MQTT.js/compare/v5.6.1...v5.6.2) (2024-05-23)


### Bug Fixes

* prevent url.parse to set `path` option ([#1871](https://github.com/mqttjs/MQTT.js/issues/1871)) ([de0174f](https://github.com/mqttjs/MQTT.js/commit/de0174f033367dde352d1eff339064e704f610e1)), closes [#1870](https://github.com/mqttjs/MQTT.js/issues/1870)

## [5.6.1](https://github.com/mqttjs/MQTT.js/compare/v5.6.0...v5.6.1) (2024-05-17)


### Bug Fixes

* update is-browser.ts to account `undefined` navigator ([#1868](https://github.com/mqttjs/MQTT.js/issues/1868)) ([0111a7a](https://github.com/mqttjs/MQTT.js/commit/0111a7af4b71f2a973a712a1f0df6574660d6ec0)), closes [/github.com/mqttjs/MQTT.js/commit/6a03d29b86dc4fe8eae04eaf0f9fc661f1c3d1ea#commitcomment-142114121](https://github.com//github.com/mqttjs/MQTT.js/commit/6a03d29b86dc4fe8eae04eaf0f9fc661f1c3d1ea/issues/commitcomment-142114121) [/github.com/mqttjs/MQTT.js/pull/1868#pullrequestreview-2062507553](https://github.com//github.com/mqttjs/MQTT.js/pull/1868/issues/pullrequestreview-2062507553)

# [5.6.0](https://github.com/mqttjs/MQTT.js/compare/v5.5.6...v5.6.0) (2024-05-13)


### Features

* keepalive manager ([#1865](https://github.com/mqttjs/MQTT.js/issues/1865)) ([bad160a](https://github.com/mqttjs/MQTT.js/commit/bad160af2a7b76a5159652e6d3757e7798337261))

## [5.5.6](https://github.com/mqttjs/MQTT.js/compare/v5.5.5...v5.5.6) (2024-05-13)


### Bug Fixes

* do not shift pings on 'publish' packets ([#1866](https://github.com/mqttjs/MQTT.js/issues/1866)) ([e4d4663](https://github.com/mqttjs/MQTT.js/commit/e4d4663bcd5f87399b9d7bf101b364cda1c48d0e)), closes [#1863](https://github.com/mqttjs/MQTT.js/issues/1863) [#1861](https://github.com/mqttjs/MQTT.js/issues/1861)
* **electron:** detect electron context ([#1856](https://github.com/mqttjs/MQTT.js/issues/1856)) ([6a03d29](https://github.com/mqttjs/MQTT.js/commit/6a03d29b86dc4fe8eae04eaf0f9fc661f1c3d1ea))
* **ws:** ignored `host` option and default hostname in browser ([c6580a6](https://github.com/mqttjs/MQTT.js/commit/c6580a6685821c60a4595986227dba2a615b9958)), closes [#1730](https://github.com/mqttjs/MQTT.js/issues/1730)

## [5.5.5](https://github.com/mqttjs/MQTT.js/compare/v5.5.4...v5.5.5) (2024-04-30)


### Bug Fixes

* keepalive issues ([#1855](https://github.com/mqttjs/MQTT.js/issues/1855)) ([4f242f4](https://github.com/mqttjs/MQTT.js/commit/4f242f47bc8568299f04bade8aa4d1d11b939912))

## [5.5.4](https://github.com/mqttjs/MQTT.js/compare/v5.5.3...v5.5.4) (2024-04-26)


### Bug Fixes

* allow to use unix sockets in connect ([#1852](https://github.com/mqttjs/MQTT.js/issues/1852)) ([22c97b5](https://github.com/mqttjs/MQTT.js/commit/22c97b5f7536e3e36317c3b28dc0d70557b820ac)), closes [#1040](https://github.com/mqttjs/MQTT.js/issues/1040)
* **react-native:** process.nextTick is not a function error ([#1849](https://github.com/mqttjs/MQTT.js/issues/1849)) ([f62e207](https://github.com/mqttjs/MQTT.js/commit/f62e207def81b174af83d2e9525cddd1ce960fc3))

## [5.5.3](https://github.com/mqttjs/MQTT.js/compare/v5.5.2...v5.5.3) (2024-04-19)


### Bug Fixes

* possible race condition in ping timer ([#1848](https://github.com/mqttjs/MQTT.js/issues/1848)) ([0b7d687](https://github.com/mqttjs/MQTT.js/commit/0b7d687282e6342d5276946dfd4c4d1e0a66ba47)), closes [#1845](https://github.com/mqttjs/MQTT.js/issues/1845)
* wrong mqttjs version printed ([#1847](https://github.com/mqttjs/MQTT.js/issues/1847)) ([a24cf14](https://github.com/mqttjs/MQTT.js/commit/a24cf14654cb0fa74da1be2671dfaf57071fec40))

## [5.5.2](https://github.com/mqttjs/MQTT.js/compare/v5.5.1...v5.5.2) (2024-04-12)


### Bug Fixes

* **react-native:** error Cannot create URL for blob ([#1840](https://github.com/mqttjs/MQTT.js/issues/1840)) ([fc8fafb](https://github.com/mqttjs/MQTT.js/commit/fc8fafbdf5e01edc487192393293b944e77f5920))

## [5.5.1](https://github.com/mqttjs/MQTT.js/compare/v5.5.0...v5.5.1) (2024-04-10)


### Bug Fixes

* **browser:** uncaught error when stream is destroyed with error ([380f286](https://github.com/mqttjs/MQTT.js/commit/380f286d46f1c3d7a64c7bd851bbe8d84b797074)), closes [#1839](https://github.com/mqttjs/MQTT.js/issues/1839)

# [5.5.0](https://github.com/mqttjs/MQTT.js/compare/v5.4.0...v5.5.0) (2024-03-18)


### Bug Fixes

* **browser:** force closing client doesn't destroy websocket correctly ([#1820](https://github.com/mqttjs/MQTT.js/issues/1820)) ([f9b1204](https://github.com/mqttjs/MQTT.js/commit/f9b1204d7e0a04bb809be6205091fd89281b1e73)), closes [#1817](https://github.com/mqttjs/MQTT.js/issues/1817)
* expose mqttjs version on `MqttClient.VERSION` ([#1821](https://github.com/mqttjs/MQTT.js/issues/1821)) ([50776a7](https://github.com/mqttjs/MQTT.js/commit/50776a74c73c188f67faf399af90cfe0957a0e1f))


### Features

* `timerVariant` option to choose between native and worker timers ([#1818](https://github.com/mqttjs/MQTT.js/issues/1818)) ([547519d](https://github.com/mqttjs/MQTT.js/commit/547519daa8353a2d8a7fe9e4ae715601570b085f))

# [5.4.0](https://github.com/mqttjs/MQTT.js/compare/v5.3.6...v5.4.0) (2024-03-13)


### Bug Fixes

* add keepalive test in webworker ([#1807](https://github.com/mqttjs/MQTT.js/issues/1807)) ([8697b06](https://github.com/mqttjs/MQTT.js/commit/8697b06cae3265422620c38b76126381502a9c17))
* improve some flaky tests ([#1801](https://github.com/mqttjs/MQTT.js/issues/1801)) ([78e8f13](https://github.com/mqttjs/MQTT.js/commit/78e8f139ee0ad61e752421b9e594bea742af9745))
* print MQTTjs version and environment on constructor ([#1816](https://github.com/mqttjs/MQTT.js/issues/1816)) ([c0a6668](https://github.com/mqttjs/MQTT.js/commit/c0a666887ec313ee82142a825166e5b1d2e668bb))
* some others flaky tests ([#1808](https://github.com/mqttjs/MQTT.js/issues/1808)) ([f988058](https://github.com/mqttjs/MQTT.js/commit/f9880588244ac35c945302fad474f6c47f27acbc))
* update worker-timers from 7.0.78 to 7.1.4 ([#1813](https://github.com/mqttjs/MQTT.js/issues/1813)) ([2b75186](https://github.com/mqttjs/MQTT.js/commit/2b751861f2af7b914c3eb84265fb8474428045ec)), closes [#1802](https://github.com/mqttjs/MQTT.js/issues/1802)
* wrong default export for browser ([#1800](https://github.com/mqttjs/MQTT.js/issues/1800)) ([6237f45](https://github.com/mqttjs/MQTT.js/commit/6237f45f3f455b1b6ae7d339fc8a56a5eff91dc2))


### Features

* emit `Keepalive timeout` error and speed up tests using fake timers ([#1798](https://github.com/mqttjs/MQTT.js/issues/1798)) ([5d9bf10](https://github.com/mqttjs/MQTT.js/commit/5d9bf1004ba76098d4ae315fa7a4b44a9d26750b))

## [5.3.6](https://github.com/mqttjs/MQTT.js/compare/v5.3.5...v5.3.6) (2024-02-26)


### Bug Fixes

* **browser:** add `navigator` polifilly for wechat mini ([#1796](https://github.com/mqttjs/MQTT.js/issues/1796)) ([c26908a](https://github.com/mqttjs/MQTT.js/commit/c26908a242fa1f573689b03f554bb95d83e61c84)), closes [#1789](https://github.com/mqttjs/MQTT.js/issues/1789)
* emit `error` event on connack timeout ([#1781](https://github.com/mqttjs/MQTT.js/issues/1781)) ([56e6e23](https://github.com/mqttjs/MQTT.js/commit/56e6e23c0fb775bfd16edf04d6b28f6bbcf05023))

## [5.3.5](https://github.com/mqttjs/MQTT.js/compare/v5.3.4...v5.3.5) (2024-01-23)


### Bug Fixes

* bump help-me version to fix vulnerability in glob/inflight ([#1773](https://github.com/mqttjs/MQTT.js/issues/1773)) ([72f99dc](https://github.com/mqttjs/MQTT.js/commit/72f99dcb33b016bced8a2c03ac857c3940ddcda3))
* keepalive causes a reconnect loop when connection is lost ([#1779](https://github.com/mqttjs/MQTT.js/issues/1779)) ([3da5e84](https://github.com/mqttjs/MQTT.js/commit/3da5e84a158985cbe7bdf60d3a9744b71d98bb56)), closes [#1778](https://github.com/mqttjs/MQTT.js/issues/1778)

## [5.3.4](https://github.com/mqttjs/MQTT.js/compare/v5.3.3...v5.3.4) (2023-12-22)


### Bug Fixes

* leaked `close` listener in `startStreamProcess` loop ([#1759](https://github.com/mqttjs/MQTT.js/issues/1759)) ([0c10ef6](https://github.com/mqttjs/MQTT.js/commit/0c10ef680ccc34bbe49948d414f36879d816e4e0))
* typo in `client.ts` ([#1763](https://github.com/mqttjs/MQTT.js/issues/1763)) ([e3528ac](https://github.com/mqttjs/MQTT.js/commit/e3528ac32d9dc165f8f1238397bd4d02e1990279))

## [5.3.3](https://github.com/mqttjs/MQTT.js/compare/v5.3.2...v5.3.3) (2023-12-05)


### Bug Fixes

* don't use worker timers in worker and add web worker tests ([#1755](https://github.com/mqttjs/MQTT.js/issues/1755)) ([38fb6ae](https://github.com/mqttjs/MQTT.js/commit/38fb6ae16073ce31e38dbc1e41a155ad98e04dcc))
* improve worker tests ([#1757](https://github.com/mqttjs/MQTT.js/issues/1757)) ([4facb18](https://github.com/mqttjs/MQTT.js/commit/4facb18dd9f81bb6af437a6257960e6e878349ad))

## [5.3.2](https://github.com/mqttjs/MQTT.js/compare/v5.3.1...v5.3.2) (2023-12-04)


### Bug Fixes

* **browser:** use worker timers to prevent unexpected client close ([#1753](https://github.com/mqttjs/MQTT.js/issues/1753)) ([35448f3](https://github.com/mqttjs/MQTT.js/commit/35448f386687030e7b68bd88f5f4852fbb833c9d))
* catch all socket errors ([#1752](https://github.com/mqttjs/MQTT.js/issues/1752)) ([a50e85c](https://github.com/mqttjs/MQTT.js/commit/a50e85ccf780621cdf2fd0a0bfcf5575a590f173))
* prop `window` is not defined in web worker ([#1749](https://github.com/mqttjs/MQTT.js/issues/1749)) ([6591404](https://github.com/mqttjs/MQTT.js/commit/6591404b38c73550157e22f3e57683a634bb919c))

## [5.3.1](https://github.com/mqttjs/MQTT.js/compare/v5.3.0...v5.3.1) (2023-11-28)


### Bug Fixes

* improve environment detection in is-browser utility ([#1744](https://github.com/mqttjs/MQTT.js/issues/1744)) ([b094142](https://github.com/mqttjs/MQTT.js/commit/b09414285d5c27cf76a9ff72cbb5ffe8ecec3981))
* typescript compile error ([2655feb](https://github.com/mqttjs/MQTT.js/commit/2655feb7a182c53bfa5ea7321b4e1a6d5b031311)), closes [#1746](https://github.com/mqttjs/MQTT.js/issues/1746)

# [5.3.0](https://github.com/mqttjs/MQTT.js/compare/v5.2.2...v5.3.0) (2023-11-18)


### Features

* **browser:** websockets improvements and bundle optimizations ([#1732](https://github.com/mqttjs/MQTT.js/issues/1732)) ([0928f85](https://github.com/mqttjs/MQTT.js/commit/0928f8575a7b4c717fbd960c802e1dc41b436d0e))

## [5.2.2](https://github.com/mqttjs/MQTT.js/compare/v5.2.1...v5.2.2) (2023-11-14)


### Bug Fixes

* add default export ([#1740](https://github.com/mqttjs/MQTT.js/issues/1740)) ([fdb498f](https://github.com/mqttjs/MQTT.js/commit/fdb498fe7ebbdf2be0d1fbcb897f093d4fa40d05))

## [5.2.1](https://github.com/mqttjs/MQTT.js/compare/v5.2.0...v5.2.1) (2023-11-10)


### Bug Fixes

* make `import mqtt from 'mqtt'` work in browsers ([#1734](https://github.com/mqttjs/MQTT.js/issues/1734)) ([80e29a9](https://github.com/mqttjs/MQTT.js/commit/80e29a9dc6bb6ad51a7ac968361a550bc1da68cb))

# [5.2.0](https://github.com/mqttjs/MQTT.js/compare/v5.1.4...v5.2.0) (2023-11-09)


### Features

* esm version `dist/mqtt.esm.js` and replace `browserify` with `esbuild` ([#1731](https://github.com/mqttjs/MQTT.js/issues/1731)) ([3d6c3be](https://github.com/mqttjs/MQTT.js/commit/3d6c3be60eae8416dbfea1d15a826c0b5fc52c45))

## [5.1.4](https://github.com/mqttjs/MQTT.js/compare/v5.1.3...v5.1.4) (2023-10-30)


### Bug Fixes

* crash with React Native ([#1724](https://github.com/mqttjs/MQTT.js/issues/1724)) ([f6123f2](https://github.com/mqttjs/MQTT.js/commit/f6123f22a11a4eb4c34c874b47056cea7ef264a6))
* unambiguously detect web workers ([#1728](https://github.com/mqttjs/MQTT.js/issues/1728)) ([e44368c](https://github.com/mqttjs/MQTT.js/commit/e44368c0d7541d005ad668d5d44d080e29ca5778))

## [5.1.3](https://github.com/mqttjs/MQTT.js/compare/v5.1.2...v5.1.3) (2023-10-20)


### Bug Fixes

* add all `EventListener` methods to `TypedEventEmitter` interface ([#1718](https://github.com/mqttjs/MQTT.js/issues/1718)) ([b96882a](https://github.com/mqttjs/MQTT.js/commit/b96882a7e5ff2869badbbd34c9b2e1ac51c25d2a))

## [5.1.2](https://github.com/mqttjs/MQTT.js/compare/v5.1.1...v5.1.2) (2023-10-10)


### Bug Fixes

* detect web worker ([#1711](https://github.com/mqttjs/MQTT.js/issues/1711)) ([a75a467](https://github.com/mqttjs/MQTT.js/commit/a75a467e3524aef1d6038ed4ed14ab0407c146cb))

## [5.1.1](https://github.com/mqttjs/MQTT.js/compare/v5.1.0...v5.1.1) (2023-10-09)


### Bug Fixes

* restore nodejs 16 compatibility ([a347c0d](https://github.com/mqttjs/MQTT.js/commit/a347c0d81ff800c1469d8497542a8c5973b59e33)), closes [#1710](https://github.com/mqttjs/MQTT.js/issues/1710)

# [5.1.0](https://github.com/mqttjs/MQTT.js/compare/v5.0.5...v5.1.0) (2023-10-04)


### Bug Fixes

* **types:** import type error ([#1705](https://github.com/mqttjs/MQTT.js/issues/1705)) ([0960b68](https://github.com/mqttjs/MQTT.js/commit/0960b68f9b612640318931e971d7a715f0945bdd))


### Features

* custom websocket support ([#1696](https://github.com/mqttjs/MQTT.js/issues/1696)) ([d6fd3a8](https://github.com/mqttjs/MQTT.js/commit/d6fd3a8316642a17ff1e90b4d6c9d4656c3831e5))

## [5.0.5](https://github.com/mqttjs/MQTT.js/compare/v5.0.4...v5.0.5) (2023-09-08)


### Bug Fixes

* publish/subscribe/unsubscribe types and missing types exports ([#1688](https://github.com/mqttjs/MQTT.js/issues/1688)) ([2df6af7](https://github.com/mqttjs/MQTT.js/commit/2df6af717a7458eff1bf69be026734c973ade0a6))

## [5.0.4](https://github.com/mqttjs/MQTT.js/compare/v5.0.3...v5.0.4) (2023-08-31)


### Bug Fixes

* export js file in dist folder ([#1596](https://github.com/mqttjs/MQTT.js/issues/1596)) ([#1677](https://github.com/mqttjs/MQTT.js/issues/1677)) ([cbe0dc6](https://github.com/mqttjs/MQTT.js/commit/cbe0dc6be52bb3a5a9fa1f5b390973bf57f9da47))
* move exported types out of dev dependencies ([#1676](https://github.com/mqttjs/MQTT.js/issues/1676)) ([844e4ff](https://github.com/mqttjs/MQTT.js/commit/844e4ff6a75911e0d5f5fad75341ffc04eed1b15))
* set default value false for reconnecting in constructor ([#1674](https://github.com/mqttjs/MQTT.js/issues/1674)) ([#1678](https://github.com/mqttjs/MQTT.js/issues/1678)) ([312b57b](https://github.com/mqttjs/MQTT.js/commit/312b57ba982209d874d65a0857a019991a2f9b0d))

## [5.0.3](https://github.com/mqttjs/MQTT.js/compare/v5.0.2...v5.0.3) (2023-08-16)


### Bug Fixes

* browser detection ([183b35a](https://github.com/mqttjs/MQTT.js/commit/183b35aa3ed98fbbcbea6805994ef7c3cc8ee616)), closes [#1671](https://github.com/mqttjs/MQTT.js/issues/1671)
* close and end callbacks not executed in the WeChat mini program ([#1664](https://github.com/mqttjs/MQTT.js/issues/1664)) ([15ff607](https://github.com/mqttjs/MQTT.js/commit/15ff607f4c938d0e7a23c99413db7496cae12e48))

## [5.0.2](https://github.com/mqttjs/MQTT.js/compare/v5.0.1...v5.0.2) (2023-08-03)


### Bug Fixes

* **cli:** cli commands not working ([#1660](https://github.com/mqttjs/MQTT.js/issues/1660)) ([1bea132](https://github.com/mqttjs/MQTT.js/commit/1bea132e97eeeb7187525dcf7417761388919075))
* import mqtt correctly in test ([8f15557](https://github.com/mqttjs/MQTT.js/commit/8f15557d0c4e455f91c96df5793d32451f1601d3))
* **tests:** abstract store test types ([0ddd097](https://github.com/mqttjs/MQTT.js/commit/0ddd0976bb8dd7dc1d434e8bb954d440ba653fb2))

## [5.0.1](https://github.com/mqttjs/MQTT.js/compare/v5.0.0...v5.0.1) (2023-07-31)


### Bug Fixes

* resubscribe when no session present ([#895](https://github.com/mqttjs/MQTT.js/issues/895)) ([#1650](https://github.com/mqttjs/MQTT.js/issues/1650)) ([37acda6](https://github.com/mqttjs/MQTT.js/commit/37acda655e202025373311624e19589ae7ef5970))
* **types:** wrong `incomingStore` and `outgoingStore` ([8133eba](https://github.com/mqttjs/MQTT.js/commit/8133eba152e81ed77e6aa18eb2cc351c3c901aa8))

# [5.0.0](https://github.com/mqttjs/MQTT.js/compare/v4.3.7...v5.0.0) (2023-07-25)


### Bug Fixes

* help message for client ID param for sub command is incorrect ([#1643](https://github.com/mqttjs/MQTT.js/issues/1643)) ([8521888](https://github.com/mqttjs/MQTT.js/commit/85218884728da85b626de6af0ac0bc9c26045f43))
* **types:** better streamBuilder types ([247e187](https://github.com/mqttjs/MQTT.js/commit/247e187b22e4ae916d1d89013e617b19688914dc))
* **types:** better types ([#1645](https://github.com/mqttjs/MQTT.js/issues/1645)) ([0f29bff](https://github.com/mqttjs/MQTT.js/commit/0f29bffb7e9088a1388139dcae04bb8731debc38))
* use explicit `connect` packet and infer types from `mqtt-packet` ([#1646](https://github.com/mqttjs/MQTT.js/issues/1646)) ([2a49ed3](https://github.com/mqttjs/MQTT.js/commit/2a49ed324e330deb5ca2ba8044b9196fc411ab8a))


### Features

* promises support ([#1644](https://github.com/mqttjs/MQTT.js/issues/1644)) ([d02e176](https://github.com/mqttjs/MQTT.js/commit/d02e17697f351b5fc2ed6d2cf689cbe40b829b9d))



# [5.0.0-beta.4](https://github.com/mqttjs/MQTT.js/compare/v4.3.7...v5.0.0) (2023-07-21)



# [5.0.0-beta.3](https://github.com/mqttjs/MQTT.js/compare/v4.3.7...v5.0.0) (2023-07-19)


### Bug Fixes

* make tests more reliable ([#1534](https://github.com/mqttjs/MQTT.js/issues/1534)) ([1076143](https://github.com/mqttjs/MQTT.js/commit/1076143a7ed6b07b91ded9985cc9a0bbb5a84da4))
* problem with publish callback invoked twice ([#1635](https://github.com/mqttjs/MQTT.js/issues/1635)) ([79b23a8](https://github.com/mqttjs/MQTT.js/commit/79b23a8f76abaceec67f063b6da0ee57a2c60697))
* **types:** subscribe definition ([#1527](https://github.com/mqttjs/MQTT.js/issues/1527)) ([debb7d9](https://github.com/mqttjs/MQTT.js/commit/debb7d93c17f5b68704c160ccd88e7e1db87d92d))


* chore!: remove unused deps, convert to ES2015 class (#1633) ([d71b000](https://github.com/mqttjs/MQTT.js/commit/d71b000773e4954c9a2ecbf4f750dac58017ef1a)), closes [#1633](https://github.com/mqttjs/MQTT.js/issues/1633)


### BREAKING CHANGES

* when creating an `MqttClient` instance `new` is now required



# [5.0.0-beta.2](https://github.com/mqttjs/MQTT.js/compare/v4.3.7...v5.0.0) (2023-07-03)


### Bug Fixes

* browser tests not working ([#1628](https://github.com/mqttjs/MQTT.js/issues/1628)) ([8775fcd](https://github.com/mqttjs/MQTT.js/commit/8775fcdad952b39fa4b79dbe912ca42033be030a))
* setImmediate polyfill ([#1626](https://github.com/mqttjs/MQTT.js/issues/1626)) ([0ed0754](https://github.com/mqttjs/MQTT.js/commit/0ed0754b95b92df51ed49ae63058b31fdba1d415))


### Features

* option to disable `writeCache` and fix leak in subscriptions ([#1622](https://github.com/mqttjs/MQTT.js/issues/1622)) ([c8aa654](https://github.com/mqttjs/MQTT.js/commit/c8aa6540dbf68ffb0d88c287e2c862b28d3fb6e6)), closes [#1535](https://github.com/mqttjs/MQTT.js/issues/1535) [#1151](https://github.com/mqttjs/MQTT.js/issues/1151)



# [5.0.0-beta.1](https://github.com/mqttjs/MQTT.js/compare/v4.3.7...v5.0.0) (2023-06-29)


### Bug Fixes

* `_storeProcessing` staying true after outStore got emptied ([#1492](https://github.com/mqttjs/MQTT.js/issues/1492)) ([f3f7be7](https://github.com/mqttjs/MQTT.js/commit/f3f7be76199115a622fde2590d44b1bb0cf57d41))
* consistency, used `this` instead of `that` ([#1618](https://github.com/mqttjs/MQTT.js/issues/1618)) ([800825b](https://github.com/mqttjs/MQTT.js/commit/800825bf619d83ef713a5b2fa1533bbf6ccac872))
* prevent store message on store when it's restored ([#1255](https://github.com/mqttjs/MQTT.js/issues/1255)) ([8d68c8c](https://github.com/mqttjs/MQTT.js/commit/8d68c8c3e38aede52741a06838933011a6fccc43))



# [5.0.0-beta.0](https://github.com/mqttjs/MQTT.js/compare/v4.3.7...v5.0.0) (2023-06-27)


### Bug Fixes

* add missing export of UniqueMessageIdProvider and DefaultMessageIdProvider ([#1572](https://github.com/mqttjs/MQTT.js/issues/1572)) ([aa2e0ad](https://github.com/mqttjs/MQTT.js/commit/aa2e0ad49aadf333141f18cb85d2582abb8e19fc))
* IS_BROWSER check is now safer and more agnostic about the bundler ([#1571](https://github.com/mqttjs/MQTT.js/issues/1571)) ([b48b4b4](https://github.com/mqttjs/MQTT.js/commit/b48b4b4e79690c96033ea2df387c11f3bc26bf6a))
* **test:** `topicAliasMaximum` tests ([#1612](https://github.com/mqttjs/MQTT.js/issues/1612)) ([f1e5518](https://github.com/mqttjs/MQTT.js/commit/f1e5518150ea45067b87104abd9fed64ec13a48c))
* topicAliasMaximum under must be under Connect properties ([#1519](https://github.com/mqttjs/MQTT.js/issues/1519)) ([3b2e1cb](https://github.com/mqttjs/MQTT.js/commit/3b2e1cb7c4bf33ff66bcd1cc3091790a9635f19a))
* **types:** missing null declaration for error in subscription callback ([#1589](https://github.com/mqttjs/MQTT.js/issues/1589)) ([afc067b](https://github.com/mqttjs/MQTT.js/commit/afc067be2ca83990209b6176adec06f9a4c76a2c))
* **types:** topic alias controls and password ([#1509](https://github.com/mqttjs/MQTT.js/issues/1509)) ([85c9341](https://github.com/mqttjs/MQTT.js/commit/85c9341bba2676cfd069ec38a1a7cfda71647b68))


* chore!: drop support for node 12-14 (#1615) ([a2cbf61](https://github.com/mqttjs/MQTT.js/commit/a2cbf61c2a051a5ee69a50e00688e8ace79e7ef5)), closes [#1615](https://github.com/mqttjs/MQTT.js/issues/1615)


### BREAKING CHANGES

* Dropped support for NodeJS 12-14

# [5.0.0-beta.4](https://github.com/mqttjs/MQTT.js/compare/v4.3.7...v5.0.0-beta.4) (2023-07-21)



# [5.0.0-beta.3](https://github.com/mqttjs/MQTT.js/compare/v4.3.7...v5.0.0-beta.4) (2023-07-19)


### Bug Fixes

* make tests more reliable ([#1534](https://github.com/mqttjs/MQTT.js/issues/1534)) ([1076143](https://github.com/mqttjs/MQTT.js/commit/1076143a7ed6b07b91ded9985cc9a0bbb5a84da4))
* problem with publish callback invoked twice ([#1635](https://github.com/mqttjs/MQTT.js/issues/1635)) ([79b23a8](https://github.com/mqttjs/MQTT.js/commit/79b23a8f76abaceec67f063b6da0ee57a2c60697))
* **types:** subscribe definition ([#1527](https://github.com/mqttjs/MQTT.js/issues/1527)) ([debb7d9](https://github.com/mqttjs/MQTT.js/commit/debb7d93c17f5b68704c160ccd88e7e1db87d92d))


* chore!: remove unused deps, convert to ES2015 class (#1633) ([d71b000](https://github.com/mqttjs/MQTT.js/commit/d71b000773e4954c9a2ecbf4f750dac58017ef1a)), closes [#1633](https://github.com/mqttjs/MQTT.js/issues/1633)


### BREAKING CHANGES

* when creating an `MqttClient` instance `new` is now required



# [5.0.0-beta.2](https://github.com/mqttjs/MQTT.js/compare/v4.3.7...v5.0.0-beta.4) (2023-07-03)


### Bug Fixes

* browser tests not working ([#1628](https://github.com/mqttjs/MQTT.js/issues/1628)) ([8775fcd](https://github.com/mqttjs/MQTT.js/commit/8775fcdad952b39fa4b79dbe912ca42033be030a))
* setImmediate polyfill ([#1626](https://github.com/mqttjs/MQTT.js/issues/1626)) ([0ed0754](https://github.com/mqttjs/MQTT.js/commit/0ed0754b95b92df51ed49ae63058b31fdba1d415))


### Features

* option to disable `writeCache` and fix leak in subscriptions ([#1622](https://github.com/mqttjs/MQTT.js/issues/1622)) ([c8aa654](https://github.com/mqttjs/MQTT.js/commit/c8aa6540dbf68ffb0d88c287e2c862b28d3fb6e6)), closes [#1535](https://github.com/mqttjs/MQTT.js/issues/1535) [#1151](https://github.com/mqttjs/MQTT.js/issues/1151)



# [5.0.0-beta.1](https://github.com/mqttjs/MQTT.js/compare/v4.3.7...v5.0.0-beta.4) (2023-06-29)


### Bug Fixes

* `_storeProcessing` staying true after outStore got emptied ([#1492](https://github.com/mqttjs/MQTT.js/issues/1492)) ([f3f7be7](https://github.com/mqttjs/MQTT.js/commit/f3f7be76199115a622fde2590d44b1bb0cf57d41))
* consistency, used `this` instead of `that` ([#1618](https://github.com/mqttjs/MQTT.js/issues/1618)) ([800825b](https://github.com/mqttjs/MQTT.js/commit/800825bf619d83ef713a5b2fa1533bbf6ccac872))
* prevent store message on store when it's restored ([#1255](https://github.com/mqttjs/MQTT.js/issues/1255)) ([8d68c8c](https://github.com/mqttjs/MQTT.js/commit/8d68c8c3e38aede52741a06838933011a6fccc43))



# [5.0.0-beta.0](https://github.com/mqttjs/MQTT.js/compare/v4.3.7...v5.0.0-beta.4) (2023-06-27)


### Bug Fixes

* add missing export of UniqueMessageIdProvider and DefaultMessageIdProvider ([#1572](https://github.com/mqttjs/MQTT.js/issues/1572)) ([aa2e0ad](https://github.com/mqttjs/MQTT.js/commit/aa2e0ad49aadf333141f18cb85d2582abb8e19fc))
* IS_BROWSER check is now safer and more agnostic about the bundler ([#1571](https://github.com/mqttjs/MQTT.js/issues/1571)) ([b48b4b4](https://github.com/mqttjs/MQTT.js/commit/b48b4b4e79690c96033ea2df387c11f3bc26bf6a))
* **test:** `topicAliasMaximum` tests ([#1612](https://github.com/mqttjs/MQTT.js/issues/1612)) ([f1e5518](https://github.com/mqttjs/MQTT.js/commit/f1e5518150ea45067b87104abd9fed64ec13a48c))
* topicAliasMaximum under must be under Connect properties ([#1519](https://github.com/mqttjs/MQTT.js/issues/1519)) ([3b2e1cb](https://github.com/mqttjs/MQTT.js/commit/3b2e1cb7c4bf33ff66bcd1cc3091790a9635f19a))
* **types:** missing null declaration for error in subscription callback ([#1589](https://github.com/mqttjs/MQTT.js/issues/1589)) ([afc067b](https://github.com/mqttjs/MQTT.js/commit/afc067be2ca83990209b6176adec06f9a4c76a2c))
* **types:** topic alias controls and password ([#1509](https://github.com/mqttjs/MQTT.js/issues/1509)) ([85c9341](https://github.com/mqttjs/MQTT.js/commit/85c9341bba2676cfd069ec38a1a7cfda71647b68))


* chore!: drop support for node 12-14 (#1615) ([a2cbf61](https://github.com/mqttjs/MQTT.js/commit/a2cbf61c2a051a5ee69a50e00688e8ace79e7ef5)), closes [#1615](https://github.com/mqttjs/MQTT.js/issues/1615)


### BREAKING CHANGES

* Dropped support for NodeJS 12-14

# [5.0.0-beta.3](https://github.com/mqttjs/MQTT.js/compare/v4.3.7...v5.0.0-beta.3) (2023-07-19)


### Bug Fixes

* make tests more reliable ([#1534](https://github.com/mqttjs/MQTT.js/issues/1534)) ([1076143](https://github.com/mqttjs/MQTT.js/commit/1076143a7ed6b07b91ded9985cc9a0bbb5a84da4))
* problem with publish callback invoked twice ([#1635](https://github.com/mqttjs/MQTT.js/issues/1635)) ([79b23a8](https://github.com/mqttjs/MQTT.js/commit/79b23a8f76abaceec67f063b6da0ee57a2c60697))
* **types:** subscribe definition ([#1527](https://github.com/mqttjs/MQTT.js/issues/1527)) ([debb7d9](https://github.com/mqttjs/MQTT.js/commit/debb7d93c17f5b68704c160ccd88e7e1db87d92d))


* chore!: remove unused deps, convert to ES2015 class (#1633) ([d71b000](https://github.com/mqttjs/MQTT.js/commit/d71b000773e4954c9a2ecbf4f750dac58017ef1a)), closes [#1633](https://github.com/mqttjs/MQTT.js/issues/1633)


### BREAKING CHANGES

* when creating an `MqttClient` instance `new` is now required



# [5.0.0-beta.2](https://github.com/mqttjs/MQTT.js/compare/v4.3.7...v5.0.0-beta.3) (2023-07-03)


### Bug Fixes

* browser tests not working ([#1628](https://github.com/mqttjs/MQTT.js/issues/1628)) ([8775fcd](https://github.com/mqttjs/MQTT.js/commit/8775fcdad952b39fa4b79dbe912ca42033be030a))
* setImmediate polyfill ([#1626](https://github.com/mqttjs/MQTT.js/issues/1626)) ([0ed0754](https://github.com/mqttjs/MQTT.js/commit/0ed0754b95b92df51ed49ae63058b31fdba1d415))


### Features

* option to disable `writeCache` and fix leak in subscriptions ([#1622](https://github.com/mqttjs/MQTT.js/issues/1622)) ([c8aa654](https://github.com/mqttjs/MQTT.js/commit/c8aa6540dbf68ffb0d88c287e2c862b28d3fb6e6)), closes [#1535](https://github.com/mqttjs/MQTT.js/issues/1535) [#1151](https://github.com/mqttjs/MQTT.js/issues/1151)



# [5.0.0-beta.1](https://github.com/mqttjs/MQTT.js/compare/v4.3.7...v5.0.0-beta.3) (2023-06-29)


### Bug Fixes

* `_storeProcessing` staying true after outStore got emptied ([#1492](https://github.com/mqttjs/MQTT.js/issues/1492)) ([f3f7be7](https://github.com/mqttjs/MQTT.js/commit/f3f7be76199115a622fde2590d44b1bb0cf57d41))
* consistency, used `this` instead of `that` ([#1618](https://github.com/mqttjs/MQTT.js/issues/1618)) ([800825b](https://github.com/mqttjs/MQTT.js/commit/800825bf619d83ef713a5b2fa1533bbf6ccac872))
* prevent store message on store when it's restored ([#1255](https://github.com/mqttjs/MQTT.js/issues/1255)) ([8d68c8c](https://github.com/mqttjs/MQTT.js/commit/8d68c8c3e38aede52741a06838933011a6fccc43))



# [5.0.0-beta.0](https://github.com/mqttjs/MQTT.js/compare/v4.3.7...v5.0.0-beta.3) (2023-06-27)


### Bug Fixes

* add missing export of UniqueMessageIdProvider and DefaultMessageIdProvider ([#1572](https://github.com/mqttjs/MQTT.js/issues/1572)) ([aa2e0ad](https://github.com/mqttjs/MQTT.js/commit/aa2e0ad49aadf333141f18cb85d2582abb8e19fc))
* IS_BROWSER check is now safer and more agnostic about the bundler ([#1571](https://github.com/mqttjs/MQTT.js/issues/1571)) ([b48b4b4](https://github.com/mqttjs/MQTT.js/commit/b48b4b4e79690c96033ea2df387c11f3bc26bf6a))
* **test:** `topicAliasMaximum` tests ([#1612](https://github.com/mqttjs/MQTT.js/issues/1612)) ([f1e5518](https://github.com/mqttjs/MQTT.js/commit/f1e5518150ea45067b87104abd9fed64ec13a48c))
* topicAliasMaximum under must be under Connect properties ([#1519](https://github.com/mqttjs/MQTT.js/issues/1519)) ([3b2e1cb](https://github.com/mqttjs/MQTT.js/commit/3b2e1cb7c4bf33ff66bcd1cc3091790a9635f19a))
* **types:** missing null declaration for error in subscription callback ([#1589](https://github.com/mqttjs/MQTT.js/issues/1589)) ([afc067b](https://github.com/mqttjs/MQTT.js/commit/afc067be2ca83990209b6176adec06f9a4c76a2c))
* **types:** topic alias controls and password ([#1509](https://github.com/mqttjs/MQTT.js/issues/1509)) ([85c9341](https://github.com/mqttjs/MQTT.js/commit/85c9341bba2676cfd069ec38a1a7cfda71647b68))


* chore!: drop support for node 12-14 (#1615) ([a2cbf61](https://github.com/mqttjs/MQTT.js/commit/a2cbf61c2a051a5ee69a50e00688e8ace79e7ef5)), closes [#1615](https://github.com/mqttjs/MQTT.js/issues/1615)


### BREAKING CHANGES

* Dropped support for NodeJS 12-14

# [5.0.0-beta.2](https://github.com/mqttjs/MQTT.js/compare/v4.3.7...v5.0.0-beta.2) (2023-07-03)


### Bug Fixes

* browser tests not working ([#1628](https://github.com/mqttjs/MQTT.js/issues/1628)) ([8775fcd](https://github.com/mqttjs/MQTT.js/commit/8775fcdad952b39fa4b79dbe912ca42033be030a))
* setImmediate polyfill ([#1626](https://github.com/mqttjs/MQTT.js/issues/1626)) ([0ed0754](https://github.com/mqttjs/MQTT.js/commit/0ed0754b95b92df51ed49ae63058b31fdba1d415))


### Features

* option to disable `writeCache` and fix leak in subscriptions ([#1622](https://github.com/mqttjs/MQTT.js/issues/1622)) ([c8aa654](https://github.com/mqttjs/MQTT.js/commit/c8aa6540dbf68ffb0d88c287e2c862b28d3fb6e6)), closes [#1535](https://github.com/mqttjs/MQTT.js/issues/1535) [#1151](https://github.com/mqttjs/MQTT.js/issues/1151)



# [5.0.0-beta.1](https://github.com/mqttjs/MQTT.js/compare/v4.3.7...v5.0.0-beta.2) (2023-06-29)


### Bug Fixes

* `_storeProcessing` staying true after outStore got emptied ([#1492](https://github.com/mqttjs/MQTT.js/issues/1492)) ([f3f7be7](https://github.com/mqttjs/MQTT.js/commit/f3f7be76199115a622fde2590d44b1bb0cf57d41))
* consistency, used `this` instead of `that` ([#1618](https://github.com/mqttjs/MQTT.js/issues/1618)) ([800825b](https://github.com/mqttjs/MQTT.js/commit/800825bf619d83ef713a5b2fa1533bbf6ccac872))
* prevent store message on store when it's restored ([#1255](https://github.com/mqttjs/MQTT.js/issues/1255)) ([8d68c8c](https://github.com/mqttjs/MQTT.js/commit/8d68c8c3e38aede52741a06838933011a6fccc43))



# [5.0.0-beta.0](https://github.com/mqttjs/MQTT.js/compare/v4.3.7...v5.0.0-beta.2) (2023-06-27)


### Bug Fixes

* add missing export of UniqueMessageIdProvider and DefaultMessageIdProvider ([#1572](https://github.com/mqttjs/MQTT.js/issues/1572)) ([aa2e0ad](https://github.com/mqttjs/MQTT.js/commit/aa2e0ad49aadf333141f18cb85d2582abb8e19fc))
* IS_BROWSER check is now safer and more agnostic about the bundler ([#1571](https://github.com/mqttjs/MQTT.js/issues/1571)) ([b48b4b4](https://github.com/mqttjs/MQTT.js/commit/b48b4b4e79690c96033ea2df387c11f3bc26bf6a))
* **test:** `topicAliasMaximum` tests ([#1612](https://github.com/mqttjs/MQTT.js/issues/1612)) ([f1e5518](https://github.com/mqttjs/MQTT.js/commit/f1e5518150ea45067b87104abd9fed64ec13a48c))
* topicAliasMaximum under must be under Connect properties ([#1519](https://github.com/mqttjs/MQTT.js/issues/1519)) ([3b2e1cb](https://github.com/mqttjs/MQTT.js/commit/3b2e1cb7c4bf33ff66bcd1cc3091790a9635f19a))
* **types:** missing null declaration for error in subscription callback ([#1589](https://github.com/mqttjs/MQTT.js/issues/1589)) ([afc067b](https://github.com/mqttjs/MQTT.js/commit/afc067be2ca83990209b6176adec06f9a4c76a2c))
* **types:** topic alias controls and password ([#1509](https://github.com/mqttjs/MQTT.js/issues/1509)) ([85c9341](https://github.com/mqttjs/MQTT.js/commit/85c9341bba2676cfd069ec38a1a7cfda71647b68))


* chore!: drop support for node 12-14 (#1615) ([a2cbf61](https://github.com/mqttjs/MQTT.js/commit/a2cbf61c2a051a5ee69a50e00688e8ace79e7ef5)), closes [#1615](https://github.com/mqttjs/MQTT.js/issues/1615)


### BREAKING CHANGES

* Dropped support for NodeJS 12-14

# [5.0.0-beta.1](https://github.com/mqttjs/MQTT.js/compare/v5.0.0-beta.0...v5.0.0-beta.1) (2023-06-29)


### Bug Fixes

* `_storeProcessing` staying true after outStore got emptied ([#1492](https://github.com/mqttjs/MQTT.js/issues/1492)) ([f3f7be7](https://github.com/mqttjs/MQTT.js/commit/f3f7be76199115a622fde2590d44b1bb0cf57d41))
* consistency, used `this` instead of `that` ([#1618](https://github.com/mqttjs/MQTT.js/issues/1618)) ([800825b](https://github.com/mqttjs/MQTT.js/commit/800825bf619d83ef713a5b2fa1533bbf6ccac872))
* prevent store message on store when it's restored ([#1255](https://github.com/mqttjs/MQTT.js/issues/1255)) ([8d68c8c](https://github.com/mqttjs/MQTT.js/commit/8d68c8c3e38aede52741a06838933011a6fccc43))



# [5.0.0-beta.0](https://github.com/mqttjs/MQTT.js/compare/v4.3.7...v5.0.0-beta.0) (2023-06-27)


### Bug Fixes

* add missing export of UniqueMessageIdProvider and DefaultMessageIdProvider ([#1572](https://github.com/mqttjs/MQTT.js/issues/1572)) ([aa2e0ad](https://github.com/mqttjs/MQTT.js/commit/aa2e0ad49aadf333141f18cb85d2582abb8e19fc))
* IS_BROWSER check is now safer and more agnostic about the bundler ([#1571](https://github.com/mqttjs/MQTT.js/issues/1571)) ([b48b4b4](https://github.com/mqttjs/MQTT.js/commit/b48b4b4e79690c96033ea2df387c11f3bc26bf6a))
* **test:** `topicAliasMaximum` tests ([#1612](https://github.com/mqttjs/MQTT.js/issues/1612)) ([f1e5518](https://github.com/mqttjs/MQTT.js/commit/f1e5518150ea45067b87104abd9fed64ec13a48c))
* topicAliasMaximum under must be under Connect properties ([#1519](https://github.com/mqttjs/MQTT.js/issues/1519)) ([3b2e1cb](https://github.com/mqttjs/MQTT.js/commit/3b2e1cb7c4bf33ff66bcd1cc3091790a9635f19a))
* **types:** missing null declaration for error in subscription callback ([#1589](https://github.com/mqttjs/MQTT.js/issues/1589)) ([afc067b](https://github.com/mqttjs/MQTT.js/commit/afc067be2ca83990209b6176adec06f9a4c76a2c))
* **types:** topic alias controls and password ([#1509](https://github.com/mqttjs/MQTT.js/issues/1509)) ([85c9341](https://github.com/mqttjs/MQTT.js/commit/85c9341bba2676cfd069ec38a1a7cfda71647b68))


* chore!: drop support for node 12-14 (#1615) ([a2cbf61](https://github.com/mqttjs/MQTT.js/commit/a2cbf61c2a051a5ee69a50e00688e8ace79e7ef5)), closes [#1615](https://github.com/mqttjs/MQTT.js/issues/1615)


### BREAKING CHANGES

* Dropped support for NodeJS 12-14



## [4.3.7](https://github.com/mqttjs/MQTT.js/compare/v4.3.6...v4.3.7) (2022-03-14)


### Bug Fixes

* fix regression from [#1401](https://github.com/mqttjs/MQTT.js/issues/1401) and allow CI test failures to break gitthub workflow ([#1443](https://github.com/mqttjs/MQTT.js/issues/1443)) ([accd78e](https://github.com/mqttjs/MQTT.js/commit/accd78e38aa82c8cc1ea04029e56494276776c87))



## [4.3.6](https://github.com/mqttjs/MQTT.js/compare/v4.3.5...v4.3.6) (2022-02-17)


### Bug Fixes

* buffer is not defined in browser ([#1420](https://github.com/mqttjs/MQTT.js/issues/1420)) ([f5ab1b5](https://github.com/mqttjs/MQTT.js/commit/f5ab1b5d2a04813178fb478a7e345c0acf544258))
* **types:** connect function proper overloads for its parameters ([#1416](https://github.com/mqttjs/MQTT.js/issues/1416)) ([28c4040](https://github.com/mqttjs/MQTT.js/commit/28c4040c21246710f7ea3e161bc4145ba916c0de))



## [4.3.5](https://github.com/mqttjs/MQTT.js/compare/v4.3.4...v4.3.5) (2022-02-07)


### Bug Fixes

* **sendPacket:** drain leak ([#1401](https://github.com/mqttjs/MQTT.js/issues/1401)) ([7ec4b8f](https://github.com/mqttjs/MQTT.js/commit/7ec4b8fd602e220f50693cb83f082dab764ed3f2))



## [4.3.4](https://github.com/mqttjs/MQTT.js/compare/v4.3.3...v4.3.4) (2022-01-06)


### Bug Fixes

* migrate LruMap from collections to lru-cache. ([#1396](https://github.com/mqttjs/MQTT.js/issues/1396)) ([5c67037](https://github.com/mqttjs/MQTT.js/commit/5c670370c603f09ee25fbaba961156f59eaee1a2))



## [4.3.3](https://github.com/mqttjs/MQTT.js/compare/v4.3.2...v4.3.3) (2022-01-05)


### Bug Fixes

* remove collections.js dependency from number-allocator. ([#1394](https://github.com/mqttjs/MQTT.js/issues/1394)) ([ee75c32](https://github.com/mqttjs/MQTT.js/commit/ee75c322d6f31a3279f5a7f15ee4122760b1cc94)), closes [#1392](https://github.com/mqttjs/MQTT.js/issues/1392)



## [4.3.2](https://github.com/mqttjs/MQTT.js/compare/v4.3.1...v4.3.2) (2021-12-29)


### Bug Fixes

* **dependency:** Updated collections.js related package version. ([#1386](https://github.com/mqttjs/MQTT.js/issues/1386)) ([df89a2e](https://github.com/mqttjs/MQTT.js/commit/df89a2edf4fa15d3f8d56cd0b8290f9ddde7ceb8))



## [4.3.1](https://github.com/mqttjs/MQTT.js/compare/v4.3.0...v4.3.1) (2021-12-24)


### Bug Fixes

* **dependencies:** remove babel-eslint and update snazzy ([#1383](https://github.com/mqttjs/MQTT.js/issues/1383)) ([66d43d4](https://github.com/mqttjs/MQTT.js/commit/66d43d4f33e6af405468c94112f3d1361af773dc))



# [4.3.0](https://github.com/mqttjs/MQTT.js/compare/v4.2.8...v4.3.0) (2021-12-22)


### Bug Fixes

* **client:** Refined Topic Alias support. (Implement [#1300](https://github.com/mqttjs/MQTT.js/issues/1300)) ([#1301](https://github.com/mqttjs/MQTT.js/issues/1301)) ([c92b877](https://github.com/mqttjs/MQTT.js/commit/c92b877292d314e3e0b5d8f84b7f4b68a266aba2))
* **README:** typo Support ([#1353](https://github.com/mqttjs/MQTT.js/issues/1353)) ([c424426](https://github.com/mqttjs/MQTT.js/commit/c424426cd6345eba1f8016335839a667b3928e40))
* **resubscribe:** message id allocate twice ([#1337](https://github.com/mqttjs/MQTT.js/issues/1337)) ([7466819](https://github.com/mqttjs/MQTT.js/commit/7466819d62a5db554e41bf75e939a90f0dc46fe6))
* **tls:** Skip TLS SNI if host is IP address ([#1311](https://github.com/mqttjs/MQTT.js/issues/1311)) ([2679952](https://github.com/mqttjs/MQTT.js/commit/2679952587a0e3e1b5fcbfd6b11fca72c65fba95))
* **type:** add properties type for IClientSubscribeOptions ([#1378](https://github.com/mqttjs/MQTT.js/issues/1378)) ([8de9394](https://github.com/mqttjs/MQTT.js/commit/8de9394fa9afd61a1e0e726b0fe9d3637ed17cc9))
* **type:** fix push properties types ([#1359](https://github.com/mqttjs/MQTT.js/issues/1359)) ([cb6bdcb](https://github.com/mqttjs/MQTT.js/commit/cb6bdcb2c6c9e23f87bb24dbd1458eb0509cb02f))
* types ([#1341](https://github.com/mqttjs/MQTT.js/issues/1341)) ([59fab36](https://github.com/mqttjs/MQTT.js/commit/59fab369d2738edcf62306a67375763d737bc4ad))
* **typescript:**  OnConnectCallback with specs expecting Connack packet ([#1333](https://github.com/mqttjs/MQTT.js/issues/1333)) ([e3e15c3](https://github.com/mqttjs/MQTT.js/commit/e3e15c3d791615a8fcab46b331678dd5a5a755a0))
* **typescript:** Use correct version of @types/ws ([#1358](https://github.com/mqttjs/MQTT.js/issues/1358)) ([6581d33](https://github.com/mqttjs/MQTT.js/commit/6581d3340602903d3434a0053eeabe7019595ea2))
* websocket and typescript ([9979443](https://github.com/mqttjs/MQTT.js/commit/997944380702c17d6b144b499685e591b3178c11))
* **websockets:** revert URL WHATWG changes ([a3dd38e](https://github.com/mqttjs/MQTT.js/commit/a3dd38ed4374b0baa359430472f34078369ef02c))


### Features

* add support for ALPN TLS extension ([#1332](https://github.com/mqttjs/MQTT.js/issues/1332)) ([06f2fd2](https://github.com/mqttjs/MQTT.js/commit/06f2fd2d7666ec462f9f21c3bd19c35797de9083))
* **client:** auth handler for enhanced auth ([#1380](https://github.com/mqttjs/MQTT.js/issues/1380)) ([d5850b7](https://github.com/mqttjs/MQTT.js/commit/d5850b7ba2653da84d53fcb57e5767e4b9cbb09d))


### Reverts

* Revert "fix: types (#1341)" (#1344) ([e6672e8](https://github.com/mqttjs/MQTT.js/commit/e6672e80a48db6273af6bde338035d473ee3305a)), closes [#1341](https://github.com/mqttjs/MQTT.js/issues/1341) [#1344](https://github.com/mqttjs/MQTT.js/issues/1344)



## [4.2.5](https://github.com/mqttjs/MQTT.js/compare/v4.2.4...v4.2.5) (2020-11-12)


### Bug Fixes

* **auth opts:** Default to null for false-y values ([#1197](https://github.com/mqttjs/MQTT.js/issues/1197)) ([6a0e50a](https://github.com/mqttjs/MQTT.js/commit/6a0e50a52214f5e3b221d9f3d0bb86c5896e84c1))



## [4.2.4](https://github.com/mqttjs/MQTT.js/compare/v4.2.3...v4.2.4) (2020-10-29)


### Bug Fixes

* **ws:** add all parts of object to opts ([#1194](https://github.com/mqttjs/MQTT.js/issues/1194)) ([6240565](https://github.com/mqttjs/MQTT.js/commit/62405653b33ec5e5e0c8077e3bc9e9ee9a335cbe))



## [4.2.3](https://github.com/mqttjs/MQTT.js/compare/v4.2.2...v4.2.3) (2020-10-27)


### Bug Fixes

* **secure:** do not override password and username ([#1190](https://github.com/mqttjs/MQTT.js/issues/1190)) ([298dbb2](https://github.com/mqttjs/MQTT.js/commit/298dbb2e7e11e390794128b694a40986497b374c))



## [4.2.2](https://github.com/mqttjs/MQTT.js/compare/v4.2.1...v4.2.2) (2020-10-27)


### Bug Fixes

* check if client connected when reconnecting ([#1162](https://github.com/mqttjs/MQTT.js/issues/1162)) ([541f201](https://github.com/mqttjs/MQTT.js/commit/541f201834968eeee5b8599e3b29d8daecd4aac4)), closes [#1152](https://github.com/mqttjs/MQTT.js/issues/1152)
* replace url.parse by WHATWG URL API ([#1147](https://github.com/mqttjs/MQTT.js/issues/1147)) ([70a247c](https://github.com/mqttjs/MQTT.js/commit/70a247c29e0b05ddd8755e7b9c8c41a4c25b431b)), closes [#1130](https://github.com/mqttjs/MQTT.js/issues/1130)
* use 'readable-stream' instead of 'stream' ([#1170](https://github.com/mqttjs/MQTT.js/issues/1170)) ([04184e1](https://github.com/mqttjs/MQTT.js/commit/04184e16d349d020a520c0f77391f421a6755816))



## [4.2.1](https://github.com/mqttjs/MQTT.js/compare/v4.2.0...v4.2.1) (2020-08-24)


### Bug Fixes

* **websocket:** browser in ws ([#1145](https://github.com/mqttjs/MQTT.js/issues/1145)) ([40177ca](https://github.com/mqttjs/MQTT.js/commit/40177cac9a7d7e829b21963e1582c3eb9c13f20a))



# [4.2.0](https://github.com/mqttjs/MQTT.js/compare/v4.1.0...v4.2.0) (2020-08-12)


### Bug Fixes

* **browser support:** correct browser detection for webpack ([#1135](https://github.com/mqttjs/MQTT.js/issues/1135)) ([eedc2b2](https://github.com/mqttjs/MQTT.js/commit/eedc2b26cd6063a0b1152432a00f70de5e0b9bae))
* **browser support:** do not use process.nextTick without check that it exists ([#1136](https://github.com/mqttjs/MQTT.js/issues/1136)) ([963e554](https://github.com/mqttjs/MQTT.js/commit/963e554d3da2e4149c6f99b4fbe3aad6e620b955))
* **mqtt stores:** improve error handling and tests ([#1133](https://github.com/mqttjs/MQTT.js/issues/1133)) ([9c61419](https://github.com/mqttjs/MQTT.js/commit/9c614192dc7f7be20f715b7236f13e0b60717dce))
* path for bin files ([#1107](https://github.com/mqttjs/MQTT.js/issues/1107)) ([43cc1d1](https://github.com/mqttjs/MQTT.js/commit/43cc1d1f96e32b022ead3c8ce9c6ff4cbe2c3820))
* **typescript:** fix payloadFormatIndicator to boolean type ([#1115](https://github.com/mqttjs/MQTT.js/issues/1115)) ([5adb12a](https://github.com/mqttjs/MQTT.js/commit/5adb12a6f73c63e47ff9acd54bbcaef4f11c4baa))


### Features

* **mqtt5:** add properties object to publish options ([e8326ce](https://github.com/mqttjs/MQTT.js/commit/e8326ce3baf06a1bcdbd70c33c5178bc06f8959a))
* **websockets:** websocket-streams to ws ([#1108](https://github.com/mqttjs/MQTT.js/issues/1108)) ([b2c1215](https://github.com/mqttjs/MQTT.js/commit/b2c121511c7437b64724e9f1e89ebcd27e3c2cce))



# [4.1.0](https://github.com/mqttjs/MQTT.js/compare/v4.0.1...v4.1.0) (2020-05-19)



## [4.0.1](https://github.com/mqttjs/MQTT.js/compare/v4.0.0...v4.0.1) (2020-05-07)


### Reverts

* Revert "docs: adding client flowchart" ([ef2d590](https://github.com/mqttjs/MQTT.js/commit/ef2d5907efd5eed14aa3f46a2bf18b42ee0b3687))



# [4.0.0](https://github.com/mqttjs/MQTT.js/compare/v3.0.0...v4.0.0) (2020-04-27)


### Bug Fixes

* remove only ([#1058](https://github.com/mqttjs/MQTT.js/issues/1058)) ([c8ee0e2](https://github.com/mqttjs/MQTT.js/commit/c8ee0e2c2380b87cab4a31a0fcabaab9100d62c7))


### Features

* **client:** error handling and test resilience ([#1076](https://github.com/mqttjs/MQTT.js/issues/1076)) ([2e46e08](https://github.com/mqttjs/MQTT.js/commit/2e46e08396f7a854ff53454bd0fa1f1d96b1dd27))
* connection error handler ([#1053](https://github.com/mqttjs/MQTT.js/issues/1053)) ([3cea393](https://github.com/mqttjs/MQTT.js/commit/3cea393e2608e4c091f6bccdcf2d7bfd703bb98b))
* support SNI on TLS ([#1055](https://github.com/mqttjs/MQTT.js/issues/1055)) ([f6534c2](https://github.com/mqttjs/MQTT.js/commit/f6534c2d8348afadc91c4d6c636447430be4642b))



# [3.0.0](https://github.com/mqttjs/MQTT.js/compare/v2.18.8...v3.0.0) (2019-05-27)


### Bug Fixes

* delete completed incoming QOS 2 messages ([#893](https://github.com/mqttjs/MQTT.js/issues/893)) ([9a39faa](https://github.com/mqttjs/MQTT.js/commit/9a39faa37a3f12f10610af2b87b5be86375dc402))



## [2.18.8](https://github.com/mqttjs/MQTT.js/compare/v2.18.7...v2.18.8) (2018-08-30)



## [2.18.7](https://github.com/mqttjs/MQTT.js/compare/v2.18.6...v2.18.7) (2018-08-26)



## [2.18.6](https://github.com/mqttjs/MQTT.js/compare/v2.18.5...v2.18.6) (2018-08-25)



## [2.18.5](https://github.com/mqttjs/MQTT.js/compare/v2.18.4...v2.18.5) (2018-08-23)



## [2.18.4](https://github.com/mqttjs/MQTT.js/compare/v2.18.3...v2.18.4) (2018-08-22)



## [2.18.3](https://github.com/mqttjs/MQTT.js/compare/v2.18.2...v2.18.3) (2018-07-19)



## [2.18.2](https://github.com/mqttjs/MQTT.js/compare/v2.18.1...v2.18.2) (2018-06-28)



## [2.18.1](https://github.com/mqttjs/MQTT.js/compare/v2.18.0...v2.18.1) (2018-06-12)



# [2.18.0](https://github.com/mqttjs/MQTT.js/compare/v2.17.0...v2.18.0) (2018-05-12)



# [2.17.0](https://github.com/mqttjs/MQTT.js/compare/v2.16.0...v2.17.0) (2018-03-25)



# [2.16.0](https://github.com/mqttjs/MQTT.js/compare/v2.15.3...v2.16.0) (2018-03-01)



## [2.15.3](https://github.com/mqttjs/MQTT.js/compare/v2.15.2...v2.15.3) (2018-02-16)



## [2.15.2](https://github.com/mqttjs/MQTT.js/compare/v2.15.1...v2.15.2) (2018-02-08)



## [2.15.1](https://github.com/mqttjs/MQTT.js/compare/v2.15.0...v2.15.1) (2018-01-09)



# [2.15.0](https://github.com/mqttjs/MQTT.js/compare/v2.14.0...v2.15.0) (2017-12-09)



# [2.14.0](https://github.com/mqttjs/MQTT.js/compare/v2.13.1...v2.14.0) (2017-11-04)



## [2.13.1](https://github.com/mqttjs/MQTT.js/compare/v2.13.0...v2.13.1) (2017-10-16)



# [2.13.0](https://github.com/mqttjs/MQTT.js/compare/v2.12.1...v2.13.0) (2017-09-12)



## [2.12.1](https://github.com/mqttjs/MQTT.js/compare/v2.12.0...v2.12.1) (2017-09-08)



# [2.12.0](https://github.com/mqttjs/MQTT.js/compare/v2.11.0...v2.12.0) (2017-08-18)



# [2.11.0](https://github.com/mqttjs/MQTT.js/compare/v2.10.0...v2.11.0) (2017-08-03)



# [2.10.0](https://github.com/mqttjs/MQTT.js/compare/v2.9.3...v2.10.0) (2017-07-31)



## [2.9.3](https://github.com/mqttjs/MQTT.js/compare/v2.9.2...v2.9.3) (2017-07-25)



## [2.9.2](https://github.com/mqttjs/MQTT.js/compare/v2.9.1...v2.9.2) (2017-07-21)



## [2.9.1](https://github.com/mqttjs/MQTT.js/compare/v2.9.0...v2.9.1) (2017-07-06)



# [2.9.0](https://github.com/mqttjs/MQTT.js/compare/v2.8.2...v2.9.0) (2017-06-16)



## [2.8.2](https://github.com/mqttjs/MQTT.js/compare/v2.8.1...v2.8.2) (2017-06-06)



## [2.8.1](https://github.com/mqttjs/MQTT.js/compare/v2.8.0...v2.8.1) (2017-06-03)



# [2.8.0](https://github.com/mqttjs/MQTT.js/compare/v2.7.2...v2.8.0) (2017-05-26)



## [2.7.2](https://github.com/mqttjs/MQTT.js/compare/v2.7.0...v2.7.2) (2017-05-15)



# [2.7.0](https://github.com/mqttjs/MQTT.js/compare/v2.6.2...v2.7.0) (2017-05-01)



## [2.6.2](https://github.com/mqttjs/MQTT.js/compare/v2.6.1...v2.6.2) (2017-04-10)



## [2.6.1](https://github.com/mqttjs/MQTT.js/compare/v2.6.0...v2.6.1) (2017-04-09)



# [2.6.0](https://github.com/mqttjs/MQTT.js/compare/v2.5.2...v2.6.0) (2017-04-07)



## [2.5.2](https://github.com/mqttjs/MQTT.js/compare/v2.5.1...v2.5.2) (2017-04-03)



## [2.5.1](https://github.com/mqttjs/MQTT.js/compare/v2.5.0...v2.5.1) (2017-04-01)



# [2.5.0](https://github.com/mqttjs/MQTT.js/compare/v2.4.0...v2.5.0) (2017-03-18)



# [2.4.0](https://github.com/mqttjs/MQTT.js/compare/v2.3.1...v2.4.0) (2017-02-14)



## [2.3.1](https://github.com/mqttjs/MQTT.js/compare/v2.3.0...v2.3.1) (2017-01-30)



# [2.3.0](https://github.com/mqttjs/MQTT.js/compare/v2.2.1...v2.3.0) (2017-01-23)



## [2.2.1](https://github.com/mqttjs/MQTT.js/compare/v2.2.0...v2.2.1) (2017-01-07)



# [2.2.0](https://github.com/mqttjs/MQTT.js/compare/v2.1.3...v2.2.0) (2017-01-04)



## [2.1.3](https://github.com/mqttjs/MQTT.js/compare/v2.1.2...v2.1.3) (2016-11-17)



## [2.1.2](https://github.com/mqttjs/MQTT.js/compare/v2.1.1...v2.1.2) (2016-11-17)



## [2.1.1](https://github.com/mqttjs/MQTT.js/compare/v2.1.0...v2.1.1) (2016-11-13)



# [2.1.0](https://github.com/mqttjs/MQTT.js/compare/v2.0.1...v2.1.0) (2016-11-13)



## [2.0.1](https://github.com/mqttjs/MQTT.js/compare/v2.0.0...v2.0.1) (2016-09-26)



# [2.0.0](https://github.com/mqttjs/MQTT.js/compare/v1.14.1...v2.0.0) (2016-09-15)



## [1.14.1](https://github.com/mqttjs/MQTT.js/compare/v1.14.0...v1.14.1) (2016-08-25)



# [1.14.0](https://github.com/mqttjs/MQTT.js/compare/v1.13.0...v1.14.0) (2016-08-17)



# [1.13.0](https://github.com/mqttjs/MQTT.js/compare/v1.12.0...v1.13.0) (2016-07-25)



# [1.12.0](https://github.com/mqttjs/MQTT.js/compare/v1.11.2...v1.12.0) (2016-06-25)



## [1.11.2](https://github.com/mqttjs/MQTT.js/compare/v1.11.1...v1.11.2) (2016-06-17)



## [1.11.1](https://github.com/mqttjs/MQTT.js/compare/v1.11.0...v1.11.1) (2016-06-16)



# [1.11.0](https://github.com/mqttjs/MQTT.js/compare/v1.10.0...v1.11.0) (2016-06-04)



# [1.10.0](https://github.com/mqttjs/MQTT.js/compare/v1.9.0...v1.10.0) (2016-04-27)



# [1.9.0](https://github.com/mqttjs/MQTT.js/compare/v1.8.0...v1.9.0) (2016-04-25)



# [1.8.0](https://github.com/mqttjs/MQTT.js/compare/v1.7.5...v1.8.0) (2016-04-10)



## [1.7.5](https://github.com/mqttjs/MQTT.js/compare/v1.7.4...v1.7.5) (2016-03-18)



## [0.17.4](https://github.com/mqttjs/MQTT.js/compare/v1.7.3...v0.17.4) (2016-03-18)



## [1.7.3](https://github.com/mqttjs/MQTT.js/compare/v1.7.2...v1.7.3) (2016-02-27)



## [1.7.2](https://github.com/mqttjs/MQTT.js/compare/v1.7.1...v1.7.2) (2016-02-18)



## [1.7.1](https://github.com/mqttjs/MQTT.js/compare/v1.7.0...v1.7.1) (2016-02-09)



# [1.7.0](https://github.com/mqttjs/MQTT.js/compare/v1.6.3...v1.7.0) (2016-01-22)



## [1.6.3](https://github.com/mqttjs/MQTT.js/compare/v1.6.2...v1.6.3) (2015-12-23)



## [1.6.2](https://github.com/mqttjs/MQTT.js/compare/v1.6.1...v1.6.2) (2015-12-20)



## [1.6.1](https://github.com/mqttjs/MQTT.js/compare/v1.6.0...v1.6.1) (2015-12-10)



# [1.6.0](https://github.com/mqttjs/MQTT.js/compare/v1.5.0...v1.6.0) (2015-11-28)



# [1.5.0](https://github.com/mqttjs/MQTT.js/compare/v1.4.3...v1.5.0) (2015-10-26)



## [1.4.3](https://github.com/mqttjs/MQTT.js/compare/v1.4.2...v1.4.3) (2015-10-02)



## [1.4.2](https://github.com/mqttjs/MQTT.js/compare/v1.4.1...v1.4.2) (2015-10-02)



## [1.4.1](https://github.com/mqttjs/MQTT.js/compare/v1.4.0...v1.4.1) (2015-09-15)



# [1.4.0](https://github.com/mqttjs/MQTT.js/compare/v1.3.5...v1.4.0) (2015-09-02)



## [1.3.5](https://github.com/mqttjs/MQTT.js/compare/v1.3.4...v1.3.5) (2015-07-12)



## [1.3.4](https://github.com/mqttjs/MQTT.js/compare/v1.3.3...v1.3.4) (2015-07-07)



## [1.3.3](https://github.com/mqttjs/MQTT.js/compare/v1.3.2...v1.3.3) (2015-07-03)



## [1.3.2](https://github.com/mqttjs/MQTT.js/compare/v1.3.1...v1.3.2) (2015-06-26)



## [1.3.1](https://github.com/mqttjs/MQTT.js/compare/v1.3.0...v1.3.1) (2015-06-22)



# [1.3.0](https://github.com/mqttjs/MQTT.js/compare/v1.2.1...v1.3.0) (2015-06-11)



## [1.2.1](https://github.com/mqttjs/MQTT.js/compare/v1.2.0...v1.2.1) (2015-06-08)



# [1.2.0](https://github.com/mqttjs/MQTT.js/compare/v1.1.5...v1.2.0) (2015-05-21)



## [1.1.5](https://github.com/mqttjs/MQTT.js/compare/v1.1.4...v1.1.5) (2015-05-15)



## [1.1.4](https://github.com/mqttjs/MQTT.js/compare/v1.1.3...v1.1.4) (2015-05-10)



## [1.1.3](https://github.com/mqttjs/MQTT.js/compare/v1.1.2...v1.1.3) (2015-04-06)



## [1.1.2](https://github.com/mqttjs/MQTT.js/compare/v1.1.1...v1.1.2) (2015-03-16)



## [1.1.1](https://github.com/mqttjs/MQTT.js/compare/v1.1.0...v1.1.1) (2015-03-12)



# [1.1.0](https://github.com/mqttjs/MQTT.js/compare/v1.0.11...v1.1.0) (2015-02-28)



## [1.0.11](https://github.com/mqttjs/MQTT.js/compare/v1.0.10...v1.0.11) (2015-02-28)



## [1.0.10](https://github.com/mqttjs/MQTT.js/compare/v1.0.9...v1.0.10) (2015-02-15)


### Reverts

* Revert "Use port for protocol when none is provided" ([ed01032](https://github.com/mqttjs/MQTT.js/commit/ed010327d4ba8370612418ba780ae7ffef66c66e))



## [1.0.9](https://github.com/mqttjs/MQTT.js/compare/v1.0.8...v1.0.9) (2015-02-13)



## [1.0.8](https://github.com/mqttjs/MQTT.js/compare/v1.0.7...v1.0.8) (2015-02-06)



## [1.0.7](https://github.com/mqttjs/MQTT.js/compare/v1.0.6...v1.0.7) (2015-02-01)



## [1.0.6](https://github.com/mqttjs/MQTT.js/compare/v1.0.5...v1.0.6) (2015-01-29)



## [1.0.5](https://github.com/mqttjs/MQTT.js/compare/v1.0.4...v1.0.5) (2015-01-22)



## [1.0.4](https://github.com/mqttjs/MQTT.js/compare/v1.0.3...v1.0.4) (2015-01-22)



## [1.0.3](https://github.com/mqttjs/MQTT.js/compare/v1.0.2...v1.0.3) (2015-01-21)



## [1.0.2](https://github.com/mqttjs/MQTT.js/compare/v1.0.1...v1.0.2) (2015-01-19)



## [1.0.1](https://github.com/mqttjs/MQTT.js/compare/v1.0.0...v1.0.1) (2015-01-13)



# [1.0.0](https://github.com/mqttjs/MQTT.js/compare/v0.3.13...v1.0.0) (2015-01-13)



## [0.3.13](https://github.com/mqttjs/MQTT.js/compare/v0.3.12...v0.3.13) (2014-11-11)



## [0.3.12](https://github.com/mqttjs/MQTT.js/compare/v0.3.11...v0.3.12) (2014-08-31)



## [0.3.11](https://github.com/mqttjs/MQTT.js/compare/v0.3.10...v0.3.11) (2014-07-11)



## [0.3.10](https://github.com/mqttjs/MQTT.js/compare/v0.3.9...v0.3.10) (2014-06-21)



## [0.3.9](https://github.com/mqttjs/MQTT.js/compare/v0.3.8...v0.3.9) (2014-05-27)



## [0.3.8](https://github.com/mqttjs/MQTT.js/compare/v0.3.7...v0.3.8) (2014-03-19)



## [0.3.7](https://github.com/mqttjs/MQTT.js/compare/v0.3.6...v0.3.7) (2013-11-28)



## [0.3.6](https://github.com/mqttjs/MQTT.js/compare/v0.3.5...v0.3.6) (2013-11-28)



## [0.3.5](https://github.com/mqttjs/MQTT.js/compare/v0.3.4...v0.3.5) (2013-11-27)



## [0.3.3](https://github.com/mqttjs/MQTT.js/compare/v0.3.2...v0.3.3) (2013-09-30)



## [0.3.2](https://github.com/mqttjs/MQTT.js/compare/v0.3.1...v0.3.2) (2013-09-19)



## [0.3.1](https://github.com/mqttjs/MQTT.js/compare/v0.3.0...v0.3.1) (2013-08-22)



# [0.3.0](https://github.com/mqttjs/MQTT.js/compare/v0.2.11...v0.3.0) (2013-08-21)


### Reverts

* Revert "Adding a little buffer to cope with slow connections." ([ff1e3ed](https://github.com/mqttjs/MQTT.js/commit/ff1e3ed8613d4d57b66318019b64f5cb160b1bb2))



## [0.2.11](https://github.com/mqttjs/MQTT.js/compare/v0.2.10...v0.2.11) (2013-07-20)



## [0.2.10](https://github.com/mqttjs/MQTT.js/compare/v0.2.9...v0.2.10) (2013-06-12)



## [0.2.9](https://github.com/mqttjs/MQTT.js/compare/v0.2.8...v0.2.9) (2013-05-29)



## [0.2.8](https://github.com/mqttjs/MQTT.js/compare/v0.2.5...v0.2.8) (2013-05-27)



## [0.2.5](https://github.com/mqttjs/MQTT.js/compare/v0.2.4...v0.2.5) (2013-03-23)



## [0.2.4](https://github.com/mqttjs/MQTT.js/compare/v0.2.3...v0.2.4) (2013-03-07)



## [0.2.3](https://github.com/mqttjs/MQTT.js/compare/v0.2.2...v0.2.3) (2013-03-07)



## [0.2.2](https://github.com/mqttjs/MQTT.js/compare/0.2.0...v0.2.2) (2013-03-06)



# [0.2.0](https://github.com/mqttjs/MQTT.js/compare/0.1.8...0.2.0) (2013-02-28)



## [0.1.8](https://github.com/mqttjs/MQTT.js/compare/v0.1.3...0.1.8) (2013-02-12)



## [0.1.3](https://github.com/mqttjs/MQTT.js/compare/v0.1.2...v0.1.3) (2012-02-06)



## [0.1.2](https://github.com/mqttjs/MQTT.js/compare/v0.1.1...v0.1.2) (2012-01-23)



## [0.1.1](https://github.com/mqttjs/MQTT.js/compare/v0.1.0...v0.1.1) (2012-01-18)



# 0.1.0 (2012-01-17)


================================================
FILE: CONTRIBUTING.md
================================================
# MQTT.js is an OPEN Open Source Project

-----------------------------------------

## What?

Individuals making significant and valuable contributions are given commit-access to the project to contribute as they see fit. This project is more like an open wiki than a standard guarded open source project.

## Rules

There are a few basic ground-rules for contributors:

1. **No `--force` pushes** or modifying the Git history in any way.
1. **Non-main branches** ought to be used for ongoing work.
1. **External API changes and significant modifications** ought to be subject to an **internal pull-request** to solicit feedback from other contributors.
1. Internal pull-requests to solicit feedback are *encouraged* for any other non-trivial contribution but left to the discretion of the contributor.
1. Contributors should attempt to adhere to the prevailing code-style.

## Releases

Declaring formal releases remains the prerogative of the project maintainer.

## Changes to this arrangement

This is an experiment and feedback is welcome! This document may also be subject to pull-requests or changes by contributors where you believe you have something valuable to add or change.

-----------------------------------------


================================================
FILE: DEVELOPMENT.md
================================================
# MQTTjs Development

This document aims to help you get started with developing MQTT.js.

## Release Process

In order to create a new release you have two options:

1. Locally run `npm run release` and follow the interactive CLI
2. Manually trigger the GitHub Action `release` workflow specifyin the type of release you want to create

## Tests

To run the tests, you can use the following command:

```sh
npm test
```

This will run both `browser` and `node` tests.

### Running specific tests

For example, you can run `node -r esbuild-register --test test/keepaliveManager.ts`

### Browser

Browser tests use [`wtr`](https://modern-web.dev/docs/test-runner/overview/) as the test runner. To build browser bundle using [esbuild](https://esbuild.github.io/) and run browser tests, you can use the following command:

```sh
npm run test:browser
```

The configuration file is [web-test-runner.config.msj](./web-test-runner.config.mjs). It starts a local broker using [aedes-cli](https://github.com/moscajs/aedes-cli) with `ws` and `wss` support and then runs the tests in 3 different browsers: `chrome`, `firefox` and `safari`.

The tests are located in the `test/browser` directory and there are also tests for service workers in the `test/browser/worker.js` directory.

When developing/debugging tests it's useful to run the tests in a single browser, for example:

```sh
npx wtr --manual --open
```

This will open the browser on `localhost:8001` and lets you choose the test to run by clicking on the link with the test name. By opening the DevTools you will be able to see the tests output and put debugger in both worker and main tests files.

Be aware that tests will use the bundled version of the library, so you need to run `npm run build` before running the tests. If you need to debug issues in the code it could be useful to enable source maps when building, in order to do this just set `sourcemap: true` in [esbuild.js](./esbuild.js) file and run `npm run build`.

### Node

For NodeJS tests we use the NodeJS [Test Runner](https://nodejs.org/api/test.html). To run the tests, you can use the following command:

```sh
npm run test:node
```

The tests are located in the `test` directory. The entrypoint of tests is `runTests.ts` file. It is used to filter the tests to run, set concurrency and create a nice looking tests summary (see reason [here](https://github.com/nodejs/help/issues/3902#issuecomment-1726033310))

When developing/debugging tests it's useful to run the tests for a single file/test, for example:

```sh
node -r esbuild-register --test --inspect test/client.ts
```

If you want to run tests using a filter, you can use the `--test-name-pattern` flag:

```sh
node -r esbuild-register --test --test-name-pattern="should resend in-flight QoS" --inspect test/client.ts
```

You can also run tests in watch mode using the `--watch` flag.

## Lint

You can run and automatically fix linting issues with

```sh
npm run lint-fix
```



================================================
FILE: LICENSE.md
================================================
The MIT License (MIT)
=====================

Copyright (c) 2015-2016 MQTT.js contributors
---------------------------------------

*MQTT.js contributors listed at <https://github.com/mqttjs/MQTT.js#contributors>*

Copyright 2011-2014 by Adam Rudd

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


================================================
FILE: README.md
================================================
# ![mqtt.js](https://raw.githubusercontent.com/mqttjs/MQTT.js/137ee0e3940c1f01049a30248c70f24dc6e6f829/MQTT.js.png)

![Github Test Status](https://github.com/mqttjs/MQTT.js/workflows/MQTT.js%20CI/badge.svg) [![codecov](https://codecov.io/gh/mqttjs/MQTT.js/branch/master/graph/badge.svg)](https://codecov.io/gh/mqttjs/MQTT.js)

[![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://github.com/mqttjs/MQTT.js/graphs/commit-activity)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/mqttjs/MQTT.js/pulls)

[![node](https://img.shields.io/node/v/mqtt.svg) ![npm](https://img.shields.io/npm/v/mqtt.svg?logo=npm)](https://www.npmjs.com/package/mqtt)
[![NPM Downloads](https://img.shields.io/npm/dm/mqtt.svg)](https://npm-compare.com/mqtt/#timeRange=THREE_YEARS)

MQTT.js is a client library for the [MQTT](http://mqtt.org/) protocol, written
in JavaScript for node.js and the browser.

## Table of Contents

- [Upgrade notes](#notes)
- [Installation](#install)
- [Example](#example)
- [React Native](#react-native)
- [Import Styles](#example)
- [Command Line Tools](#cli)
- [API](#api)
- [Browser](#browser)
- [About QoS](#qos)
- [TypeScript](#typescript)
- [Weapp and Ali support](#weapp-alipay)
- [Contributing](#contributing)
- [Sponsor](#sponsor)
- [License](#license)

MQTT.js is an OPEN Open Source Project, see the [Contributing](#contributing) section to find out what this means.

[![JavaScript Style
Guide](https://cdn.rawgit.com/feross/standard/master/badge.svg)](https://github.com/feross/standard)

<a name="notes"></a>

## Important notes for existing users

**v5.0.0** (07/2023)

- Removes support for all end of life node versions (v12 and v14), and now supports node v18 and v20.
- Completely rewritten in Typescript 🚀.
- When creating `MqttClient` instance `new` is now required.

**v4.0.0** (Released 04/2020) removes support for all end of life node versions, and now supports node v12 and v14. It also adds improvements to
debug logging, along with some feature additions.

As a **breaking change**, by default a error handler is built into the MQTT.js client, so if any
errors are emitted and the user has not created an event handler on the client for errors, the client will
not break as a result of unhandled errors. Additionally, typical TLS errors like `ECONNREFUSED`, `ECONNRESET` have been
added to a list of TLS errors that will be emitted from the MQTT.js client, and so can be handled as connection errors.

**v3.0.0** adds support for MQTT 5, support for node v10.x, and many fixes to improve reliability.

**Note:** MQTT v5 support is experimental as it has not been implemented by brokers yet.

**v2.0.0** removes support for node v0.8, v0.10 and v0.12, and it is 3x faster in sending
packets. It also removes all the deprecated functionality in v1.0.0,
mainly `mqtt.createConnection` and `mqtt.Server`. From v2.0.0,
subscriptions are restored upon reconnection if `clean: true`.
v1.x.x is now in _LTS_, and it will keep being supported as long as
there are v0.8, v0.10 and v0.12 users.

As a **breaking change**, the `encoding` option in the old client is
removed, and now everything is UTF-8 with the exception of the
`password` in the CONNECT message and `payload` in the PUBLISH message,
which are `Buffer`.

Another **breaking change** is that MQTT.js now defaults to MQTT v3.1.1,
so to support old brokers, please read the [client options doc](#client).

**v1.0.0** improves the overall architecture of the project, which is now
split into three components: MQTT.js keeps the Client,
[mqtt-connection](http://npm.im/mqtt-connection) includes the barebone
Connection code for server-side usage, and [mqtt-packet](http://npm.im/mqtt-packet)
includes the protocol parser and generator. The new Client improves
performance by a 30% factor, embeds Websocket support
([MOWS](http://npm.im/mows) is now deprecated), and it has a better
support for QoS 1 and 2. The previous API is still supported but
deprecated, as such, it is not documented in this README.

<a name="install"></a>

## Installation

```sh
npm install mqtt --save
```

<a name="example"></a>

## Example

For the sake of simplicity, let's put the subscriber and the publisher in the same file:

```js
const mqtt = require("mqtt");
const client = mqtt.connect("mqtt://test.mosquitto.org");

client.on("connect", () => {
  client.subscribe("presence", (err) => {
    if (!err) {
      client.publish("presence", "Hello mqtt");
    }
  });
});

client.on("message", (topic, message) => {
  // message is Buffer
  console.log(message.toString());
  client.end();
});
```

output:

```sh
Hello mqtt
```

<a name="example-react-native"></a>

### React Native

MQTT.js can be used in React Native applications. To use it, see the [React Native example](https://github.com/MaximoLiberata/react-native-mqtt.js-example)

If you want to run your own MQTT broker, you can use
[Mosquitto](http://mosquitto.org) or
[Aedes-cli](https://github.com/moscajs/aedes-cli), and launch it.

You can also use a test instance: test.mosquitto.org.

If you do not want to install a separate broker, you can try using the
[Aedes](https://github.com/moscajs/aedes).

<a name="import_styles"></a>

## Import styles

### CommonJS (Require)

```js
const mqtt = require("mqtt")  // require mqtt
const client = mqtt.connect("mqtt://test.mosquitto.org")  // create a client
```

### ES6 Modules (Import)

#### Default import

```js
import mqtt from "mqtt"; // import namespace "mqtt"
let client = mqtt.connect("mqtt://test.mosquitto.org"); // create a client
```

#### Importing individual components

```js
import { connect } from "mqtt"; // import connect from mqtt
let client = connect("mqtt://test.mosquitto.org"); // create a client
```

<a name="cli"></a>

## Command Line Tools

MQTT.js bundles a command to interact with a broker.
In order to have it available on your path, you should install MQTT.js
globally:

```sh
npm install mqtt -g
```

Then, on one terminal

```sh
mqtt sub -t 'hello' -h 'test.mosquitto.org' -v
```

On another

```sh
mqtt pub -t 'hello' -h 'test.mosquitto.org' -m 'from MQTT.js'
```

See `mqtt help <command>` for the command help.

<a name="debug"></a>

## Debug Logs

MQTT.js uses the [debug](https://www.npmjs.com/package/debug#cmd) package for debugging purposes. To enable debug logs, add the following environment variable on runtime :

```ps
# (example using PowerShell, the VS Code default)
$env:DEBUG='mqttjs*'
```

<a name="reconnecting"></a>

## About Reconnection

An important part of any websocket connection is what to do when a connection
drops off and the client needs to reconnect. MQTT has built-in reconnection
support that can be configured to behave in ways that suit the application.

#### Refresh Authentication Options / Signed Urls with `transformWsUrl` (Websocket Only)

When an mqtt connection drops and needs to reconnect, it's common to require
that any authentication associated with the connection is kept current with
the underlying auth mechanism. For instance some applications may pass an auth
token with connection options on the initial connection, while other cloud
services may require a url be signed with each connection.

By the time the reconnect happens in the application lifecycle, the original
auth data may have expired.

To address this we can use a hook called `transformWsUrl` to manipulate
either of the connection url or the client options at the time of a reconnect.

Example (update clientId & username on each reconnect):

```js
    const transformWsUrl = (url, options, client) => {
      client.options.username = `token=${this.get_current_auth_token()}`;
      client.options.clientId = `${this.get_updated_clientId()}`;

      return `${this.get_signed_cloud_url(url)}`;
    }

    const connection = await mqtt.connectAsync(<wss url>, {
      ...,
      transformWsUrl: transformUrl,
    });

```

Now every time a new WebSocket connection is opened (hopefully not too often),
we will get a fresh signed url or fresh auth token data.

Note: Currently this hook does _not_ support promises, meaning that in order to
use the latest auth token, you must have some outside mechanism running that
handles application-level authentication refreshing so that the websocket
connection can simply grab the latest valid token or signed url.

#### Customize Websockets with `createWebsocket` (Websocket Only)

When you need to add a custom websocket subprotocol or header to open a connection
through a proxy with custom authentication this callback allows you to create your own
instance of a websocket which will be used in the mqtt client.

```js
  const createWebsocket = (url, websocketSubProtocols, options) => {
    const subProtocols = [
      websocketSubProtocols[0],
      'myCustomSubprotocolOrOAuthToken',
    ]
    return new WebSocket(url, subProtocols)
  }

  const client = await mqtt.connectAsync(<wss url>, {
    ...,
    createWebsocket: createWebsocket,
  });
```

#### Enabling Reconnection with `reconnectPeriod` option

To ensure that the mqtt client automatically tries to reconnect when the
connection is dropped, you must set the client option `reconnectPeriod` to a
value greater than 0. A value of 0 will disable reconnection and then terminate
the final connection when it drops.

The default value is 1000 ms which means it will try to reconnect 1 second
after losing the connection.

Note that this will only enable reconnects after either a connection timeout, or
after a successful connection. It will _not_ (by default) enable retrying
connections that are actively denied with a CONNACK error by the server.

To also enable automatic reconnects for CONNACK errors, set
`reconnectOnConnackError: true`.

<a name="topicalias"></a>

## About Topic Alias Management

### Enabling automatic Topic Alias using

If the client sets the option `autoUseTopicAlias:true` then MQTT.js uses existing topic alias automatically.

example scenario:

```bash
1. PUBLISH topic:'t1', ta:1                   (register)
2. PUBLISH topic:'t1'       -> topic:'', ta:1 (auto use existing map entry)
3. PUBLISH topic:'t2', ta:1                   (register overwrite)
4. PUBLISH topic:'t2'       -> topic:'', ta:1 (auto use existing map entry based on the receent map)
5. PUBLISH topic:'t1'                         (t1 is no longer mapped to ta:1)
```

User doesn't need to manage which topic is mapped to which topic alias.
If the user want to register topic alias, then publish topic with topic alias.
If the user want to use topic alias, then publish topic without topic alias. If there is a mapped topic alias then added it as a property and update the topic to empty string.

### Enabling automatic Topic Alias assign

If the client sets the option `autoAssignTopicAlias:true` then MQTT.js uses existing topic alias automatically.
If no topic alias exists, then assign a new vacant topic alias automatically. If topic alias is fully used, then LRU(Least Recently Used) topic-alias entry is overwritten.

example scenario:

```bash
The broker returns CONNACK (TopicAliasMaximum:3)
1. PUBLISH topic:'t1' -> 't1', ta:1 (auto assign t1:1 and register)
2. PUBLISH topic:'t1' -> ''  , ta:1 (auto use existing map entry)
3. PUBLISH topic:'t2' -> 't2', ta:2 (auto assign t1:2 and register. 2 was vacant)
4. PUBLISH topic:'t3' -> 't3', ta:3 (auto assign t1:3 and register. 3 was vacant)
5. PUBLISH topic:'t4' -> 't4', ta:1 (LRU entry is overwritten)
```

Also user can manually register topic-alias pair using PUBLISH topic:'some', ta:X. It works well with automatic topic alias assign.

<a name="api"></a>

## API

- [`mqtt.connect()`](#connect)
- [`mqtt.connectAsync()`](#connect-async)
- [`mqtt.Client()`](#client)
- [`mqtt.Client#connect()`](#client-connect)
- [`mqtt.Client#publish()`](#publish)
- [`mqtt.Client#publishAsync()`](#publish-async)
- [`mqtt.Client#subscribe()`](#subscribe)
- [`mqtt.Client#subscribeAsync()`](#subscribe-async)
- [`mqtt.Client#unsubscribe()`](#unsubscribe)
- [`mqtt.Client#unsubscribeAsync()`](#unsubscribe-async)
- [`mqtt.Client#end()`](#end)
- [`mqtt.Client#endAsync()`](#end-async)
- [`mqtt.Client#removeOutgoingMessage()`](#removeOutgoingMessage)
- [`mqtt.Client#reconnect()`](#reconnect)
- [`mqtt.Client#handleMessage()`](#handleMessage)
- [`mqtt.Client#connected`](#connected)
- [`mqtt.Client#reconnecting`](#reconnecting)
- [`mqtt.Client#getLastMessageId()`](#getLastMessageId)
- [`mqtt.Store()`](#store)
- [`mqtt.Store#put()`](#put)
- [`mqtt.Store#del()`](#del)
- [`mqtt.Store#createStream()`](#createStream)
- [`mqtt.Store#close()`](#close)

---

<a name="connect"></a>

### mqtt.connect([url], options)

Connects to the broker specified by the given url and options and
returns a [Client](#client).

The URL can be on the following protocols: 'mqtt', 'mqtts', 'tcp',
'tls', 'ws', 'wss', 'wxs', 'alis'. If you are trying to connect to a unix socket just append the `+unix` suffix to the protocol (ex: `mqtt+unix`). This will set the `unixSocket` property automatically.

The URL can also be an object as returned by
[`URL.parse()`](http://nodejs.org/api/url.html#url_url_parse_urlstr_parsequerystring_slashesdenotehost),
in that case the two objects are merged, i.e. you can pass a single
object with both the URL and the connect options.

You can also specify a `servers` options with content: `[{ host:
'localhost', port: 1883 }, ... ]`, in that case that array is iterated
at every connect.

For all MQTT-related options, see the [Client](#client)
constructor.

<a name="connect-async"></a>

### connectAsync([url], options)

Asynchronous wrapper around the [`connect`](#connect) function.

Returns a `Promise` that resolves to a `mqtt.Client` instance when the client
fires a `'connect'` or `'end'` event, or rejects with an error if the `'error'`
is fired.

Note that the `manualConnect` option will cause the promise returned by this
function to never resolve or reject as the underlying client never fires any
events.

---

<a name="client"></a>

### mqtt.Client(streamBuilder, options)

The `Client` class wraps a client connection to an
MQTT broker over an arbitrary transport method (TCP, TLS,
WebSocket, ecc).
`Client` is an [EventEmitter](https://nodejs.org/en/learn/asynchronous-work/the-nodejs-event-emitter) that has it's own [events](#events)

`Client` automatically handles the following:

- Regular server pings
- QoS flow
- Automatic reconnections
- Start publishing before being connected

The arguments are:

- `streamBuilder` is a function that returns a subclass of the `Stream` class that supports
  the `connect` event. Typically a `net.Socket`.
- `options` is the client connection options (see: the [connect packet](https://github.com/mcollina/mqtt-packet#connect)). Defaults:
  - `wsOptions`: is the WebSocket connection options. Default is `{}`.
    It's specific for WebSockets. For possible options have a look at: <https://github.com/websockets/ws/blob/master/doc/ws.md>.
  - `keepalive`: `60` seconds, set to `0` to disable
  - `reschedulePings`: reschedule ping messages after sending packets (default `true`)
  - `clientId`: `'mqttjs_' + Math.random().toString(16).substr(2, 8)`
  - `protocolId`: `'MQTT'`
  - `protocolVersion`: `4`
  - `clean`: `true`, set to false to receive QoS 1 and 2 messages while
    offline
  - `reconnectPeriod`: `1000` milliseconds, interval between two
    reconnections. Disable auto reconnect by setting to `0`.
  - `reconnectOnConnackError`: `false`, whether to also reconnect if a CONNACK
    is received with an error.
  - `connectTimeout`: `30 * 1000` milliseconds, time to wait before a
    CONNACK is received
  - `username`: the username required by your broker, if any
  - `password`: the password required by your broker, if any
  - `socksProxy`: establish TCP and TLS connections via a socks proxy (URL, supported protocols are `socks5://`, `socks5h://`, `socks4://`, `socks4a://`)
  - `socksTimeout`: timeout for connecting to the socks proxy
  - `incomingStore`: a [Store](#store) for the incoming packets
  - `outgoingStore`: a [Store](#store) for the outgoing packets
  - `queueQoSZero`: if connection is broken, queue outgoing QoS zero messages (default `true`)
  - `customHandleAcks`: MQTT 5 feature of custom handling puback and pubrec packets. Its callback:

    ```js
      customHandleAcks: function(topic, message, packet, done) {/*some logic with calling done(error, reasonCode)*/}
    ```

  - `autoUseTopicAlias`: enabling automatic Topic Alias using functionality
  - `autoAssignTopicAlias`: enabling automatic Topic Alias assign functionality
  - `properties`: properties MQTT 5.0.
    `object` that supports the following properties:
    - `sessionExpiryInterval`: representing the Session Expiry Interval in seconds `number`,
    - `receiveMaximum`: representing the Receive Maximum value `number`,
    - `maximumPacketSize`: representing the Maximum Packet Size the Client is willing to accept `number`,
    - `topicAliasMaximum`: representing the Topic Alias Maximum value indicates the highest value that the Client will accept as a Topic Alias sent by the Server `number`,
    - `requestResponseInformation`: The Client uses this value to request the Server to return Response Information in the CONNACK `boolean`,
    - `requestProblemInformation`: The Client uses this value to indicate whether the Reason String or User Properties are sent in the case of failures `boolean`,
    - `userProperties`: The User Property is allowed to appear multiple times to represent multiple name, value pairs `object`,
    - `authenticationMethod`: the name of the authentication method used for extended authentication `string`,
    - `authenticationData`: Binary Data containing authentication data `binary`
  - `authPacket`: settings for auth packet `object`
  - `will`: a message that will sent by the broker automatically when
    the client disconnect badly. The format is:
    - `topic`: the topic to publish
    - `payload`: the message to publish
    - `qos`: the QoS
    - `retain`: the retain flag
    - `properties`: properties of will by MQTT 5.0:
      - `willDelayInterval`: representing the Will Delay Interval in seconds `number`,
      - `payloadFormatIndicator`: Will Message is UTF-8 Encoded Character Data or not `boolean`,
      - `messageExpiryInterval`: value is the lifetime of the Will Message in seconds and is sent as the Publication Expiry Interval when the Server publishes the Will Message `number`,
      - `contentType`: describing the content of the Will Message `string`,
      - `responseTopic`: String which is used as the Topic Name for a response message `string`,
      - `correlationData`: The Correlation Data is used by the sender of the Request Message to identify which request the Response Message is for when it is received `binary`,
      - `userProperties`: The User Property is allowed to appear multiple times to represent multiple name, value pairs `object`
  - `transformWsUrl` : optional `(url, options, client) => url` function
    For ws/wss protocols only. Can be used to implement signing
    urls which upon reconnect can have become expired.
  - `createWebsocket` : optional `url, websocketSubProtocols, options) => Websocket` function
      For ws/wss protocols only. Can be used to implement a custom websocket subprotocol or implementation.
  - `resubscribe` : if connection is broken and reconnects,
    subscribed topics are automatically subscribed again (default `true`)
  - `subscribeBatchSize` : optional `number`
    Maximum number of topics per SUBSCRIBE packet. When the number of topics to subscribe exceeds this value, the client will automatically split them into multiple SUBSCRIBE packets of this size.
  - `messageIdProvider`: custom messageId provider. when `new UniqueMessageIdProvider()` is set, then non conflict messageId is provided.
  - `log`: custom log function. Default uses [debug](https://www.npmjs.com/package/debug) package.
  - `manualConnect`: prevents the constructor to call `connect`. In this case after the `mqtt.connect` is called you should call `client.connect` manually.
  - `timerVariant`: defaults to `auto`, which tries to determine which timer is most appropriate for you environment, if you're having detection issues, you can set it to `worker` or `native`. If none suits you, you can pass a timer object with set and clear properties:
    ```js
    timerVariant: {
      set: (func, timer) => setInterval(func, timer),
      clear: (id) => clearInterval(id)
    }
    ```
  - `forceNativeWebSocket`: set to true if you're having detection issues (i.e. the `ws does not work in the browser` exception) to force the use of native WebSocket. It is important to note that if set to true for the first client created, then all the clients will use native WebSocket. And conversely, if not set or set to false, all will use the detection result.
  - `unixSocket`: if you want to connect to a unix socket, set this to true

Instead of setting `socksProxy` you can also supple the same parameter via the environment variable `MQTTJS_SOCKS_PROXY`.

In case mqtts (mqtt over tls) is required, the `options` object is passed through to [`tls.connect()`](http://nodejs.org/api/tls.html#tls_tls_connect_options_callback). If using a **self-signed certificate**, set `rejectUnauthorized: false`. However, be cautious as this exposes you to potential man in the middle attacks and isn't recommended for production.

For those supporting multiple TLS protocols on a single port, like MQTTS and MQTT over WSS, utilize the `ALPNProtocols` option. This lets you define the Application Layer Protocol Negotiation (ALPN) protocol. You can set `ALPNProtocols` as a string array, Buffer, or Uint8Array based on your setup.

If you are connecting to a broker that supports only MQTT 3.1 (not
3.1.1 compliant), you should pass these additional options:

```js
{
  protocolId: 'MQIsdp',
  protocolVersion: 3
}
```

This is confirmed on RabbitMQ 3.2.4, and on Mosquitto < 1.3. Mosquitto
version 1.3 and 1.4 works fine without those.

<a name="events"></a>

#### Event `'connect'`

`function (connack) {}`

Emitted on successful (re)connection (i.e. connack rc=0).

- `connack` received connack packet. When `clean` connection option is `false` and server has a previous session
  for `clientId` connection option, then `connack.sessionPresent` flag is `true`. When that is the case,
  you may rely on stored session and prefer not to send subscribe commands for the client.

#### Event `'reconnect'`

`function () {}`

Emitted when a reconnect starts.

#### Event `'close'`

`function () {}`

Emitted after a disconnection.

#### Event `'disconnect'`

`function (packet) {}`

Emitted after receiving disconnect packet from broker. MQTT 5.0 feature.

#### Event `'offline'`

`function () {}`

Emitted when the client goes offline.

#### Event `'error'`

`function (error) {}`

Emitted when the client cannot connect (i.e. connack rc != 0) or when a
parsing error occurs.

The following TLS errors will be emitted as an `error` event:

- `ECONNREFUSED`
- `ECONNRESET`
- `EADDRINUSE`
- `ENOTFOUND`

#### Event `'end'`

`function () {}`

Emitted when [`mqtt.Client#end()`](#end) is called.
If a callback was passed to `mqtt.Client#end()`, this event is emitted once the
callback returns.

#### Event `'message'`

`function (topic, message, packet) {}`

Emitted when the client receives a publish packet

- `topic` topic of the received packet
- `message` payload of the received packet
- `packet` received packet, as defined in
  [mqtt-packet](https://github.com/mcollina/mqtt-packet#publish)

#### Event `'packetsend'`

`function (packet) {}`

Emitted when the client sends any packet. This includes .published() packets
as well as packets used by MQTT for managing subscriptions and connections

- `packet` received packet, as defined in
  [mqtt-packet](https://github.com/mcollina/mqtt-packet)

#### Event `'packetreceive'`

`function (packet) {}`

Emitted when the client receives any packet. This includes packets from
subscribed topics as well as packets used by MQTT for managing subscriptions
and connections

- `packet` received packet, as defined in
  [mqtt-packet](https://github.com/mcollina/mqtt-packet)

---

<a name="client-connect"></a>

### mqtt.Client#connect()

By default client connects when constructor is called. To prevent this you can set `manualConnect` option to `true` and call `client.connect()` manually.

<a name="publish"></a>

### mqtt.Client#publish(topic, message, [options], [callback])

Publish a message to a topic

- `topic` is the topic to publish to, `String`
- `message` is the message to publish, `Buffer` or `String`
- `options` is the options to publish with, including:
  - `qos` QoS level, `Number`, default `0`
  - `retain` retain flag, `Boolean`, default `false`
  - `dup` mark as duplicate flag, `Boolean`, default `false`
  - `properties`: MQTT 5.0 properties `object`
    - `payloadFormatIndicator`: Payload is UTF-8 Encoded Character Data or not `boolean`,
    - `messageExpiryInterval`: the lifetime of the Application Message in seconds `number`,
    - `topicAlias`: value that is used to identify the Topic instead of using the Topic Name `number`,
    - `responseTopic`: String which is used as the Topic Name for a response message `string`,
    - `correlationData`: used by the sender of the Request Message to identify which request the Response Message is for when it is received `binary`,
    - `userProperties`: The User Property is allowed to appear multiple times to represent multiple name, value pairs `object`,
    - `subscriptionIdentifier`: representing the identifier of the subscription `number`,
    - `contentType`: String describing the content of the Application Message `string`
  - `cbStorePut` - `function ()`, fired when message is put into `outgoingStore` if QoS is `1` or `2`.
- `callback` - `function (err, packet)`, fired when the QoS handling completes,
  or at the next tick if QoS 0. An error occurs if client is disconnecting.

<a name="publish-async"></a>

### mqtt.Client#publishAsync(topic, message, [options])

Async [`publish`](#publish). Returns a `Promise<Packet | undefined>`.

A packet is anything that has a `messageId` property.
---

<a name="subscribe"></a>

### mqtt.Client#subscribe(topic/topic array/topic object, [options], [callback])

Subscribe to a topic or topics

- `topic` is a `String` topic to subscribe to or an `Array` of
  topics to subscribe to. It can also be an object, it has as object
  keys the topic name and as value the QoS, like `{'test1': {qos: 0}, 'test2': {qos: 1}}`.
  MQTT `topic` wildcard characters are supported (`+` - for single level and `#` - for multi level)
- `options` is the options to subscribe with, including:
  - `qos` QoS subscription level, default 0
  - `nl` No Local MQTT 5.0 flag (If the value is true, Application Messages MUST NOT be forwarded to a connection with a ClientID equal to the ClientID of the publishing connection)
  - `rap` Retain as Published MQTT 5.0 flag (If true, Application Messages forwarded using this subscription keep the RETAIN flag they were published with. If false, Application Messages forwarded using this subscription have the RETAIN flag set to 0.)
  - `rh` Retain Handling MQTT 5.0 (This option specifies whether retained messages are sent when the subscription is established.)
  - `properties`: `object`
    - `subscriptionIdentifier`: representing the identifier of the subscription `number`,
    - `userProperties`: The User Property is allowed to appear multiple times to represent multiple name, value pairs `object`
- `callback` - `function (err, granted)`
  callback fired on suback where:
  - `err` a subscription error or an error that occurs when client is disconnecting
  - `granted` is an array of `{topic, qos}` where:
    - `topic` is a subscribed to topic
    - `qos` is the granted QoS level on it

<a name="subscribe-async"></a>

### mqtt.Client#subscribeAsync(topic/topic array/topic object, [options])

Async [`subscribe`](#subscribe). Returns a `Promise<ISubscriptionGrant[]>`.

---

<a name="unsubscribe"></a>

### mqtt.Client#unsubscribe(topic/topic array, [options], [callback])

Unsubscribe from a topic or topics

- `topic` is a `String` topic or an array of topics to unsubscribe from
- `options`: options of unsubscribe.
  - `properties`: `object`
    - `userProperties`: The User Property is allowed to appear multiple times to represent multiple name, value pairs `object`
- `callback` - `function (err)`, fired on unsuback. An error occurs if client is disconnecting.

<a name="unsubscribe-async"></a>

### mqtt.Client#unsubscribeAsync(topic/topic array, [options])

Async [`unsubscribe`](#unsubscribe). Returns a `Promise<void>`.

---

<a name="end"></a>

### mqtt.Client#end([force], [options], [callback])

Close the client, accepts the following options:

- `force`: passing it to true will close the client right away, without
  waiting for the in-flight messages to be acked. This parameter is
  optional.
- `options`: options of disconnect.
  - `reasonCode`: Disconnect Reason Code `number`
  - `properties`: `object`
    - `sessionExpiryInterval`: representing the Session Expiry Interval in seconds `number`,
    - `reasonString`: representing the reason for the disconnect `string`,
    - `userProperties`: The User Property is allowed to appear multiple times to represent multiple name, value pairs `object`,
    - `serverReference`: String which can be used by the Client to identify another Server to use `string`
- `callback`: will be called when the client is closed. This parameter is
  optional.

<a name="end-async"></a>

### mqtt.Client#endAsync([force], [options])

Async [`end`](#end). Returns a `Promise<void>`.

---

<a name="removeOutgoingMessage"></a>

### mqtt.Client#removeOutgoingMessage(mId)

Remove a message from the outgoingStore.
The outgoing callback will be called with Error('Message removed') if the message is removed.

After this function is called, the messageId is released and becomes reusable.

- `mId`: The messageId of the message in the outgoingStore.

---

<a name="reconnect"></a>

### mqtt.Client#reconnect()

Connect again using the same options as connect()

---

<a name="handleMessage"></a>

### mqtt.Client#handleMessage(packet, callback)

Handle messages with backpressure support, one at a time.
Override at will, but **always call `callback`**, or the client
will hang.

---

<a name="connected"></a>

### mqtt.Client#connected

Boolean : set to `true` if the client is connected. `false` otherwise.

---

<a name="getLastMessageId"></a>

### mqtt.Client#getLastMessageId()

Number : get last message id. This is for sent messages only.

---

<a name="reconnecting"></a>

### mqtt.Client#reconnecting

Boolean : set to `true` if the client is trying to reconnect to the server. `false` otherwise.

---

<a name="store"></a>

### mqtt.Store(options)

In-memory implementation of the message store.

- `options` is the store options:
  - `clean`: `true`, clean inflight messages when close is called (default `true`)

Other implementations of `mqtt.Store`:

- [mqtt-jsonl-store](https://github.com/robertsLando/mqtt-jsonl-store) which uses
  [jsonl-db](https://github.com/AlCalzone/jsonl-db) to store inflight data, it works only on Node.
- [mqtt-level-store](http://npm.im/mqtt-level-store) which uses
  [Level-browserify](http://npm.im/level-browserify) to store the inflight
  data, making it usable both in Node and the Browser.
- [mqtt-nedb-store](https://github.com/behrad/mqtt-nedb-store) which
  uses [nedb](https://www.npmjs.com/package/nedb) to store the inflight
  data.
- [mqtt-localforage-store](http://npm.im/mqtt-localforage-store) which uses
  [localForage](http://npm.im/localforage) to store the inflight
  data, making it usable in the Browser without browserify.

---

<a name="put"></a>

### mqtt.Store#put(packet, callback)

Adds a packet to the store, a packet is
anything that has a `messageId` property.
The callback is called when the packet has been stored.

---

<a name="createStream"></a>

### mqtt.Store#createStream()

Creates a stream with all the packets in the store.

---

<a name="del"></a>

### mqtt.Store#del(packet, cb)

Removes a packet from the store, a packet is
anything that has a `messageId` property.
The callback is called when the packet has been removed.

---

<a name="close"></a>

### mqtt.Store#close(cb)

Closes the Store.

<a name="browser"></a>
<a name="webpack"></a>
<a name="vite"></a>

## Browser

> [!IMPORTANT]
> The only protocol supported in browsers is MQTT over WebSockets, so you must use `ws://` or `wss://` protocols.

While the [ws](https://www.npmjs.com/package/ws) module is used in NodeJS, [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) is used in browsers. This is totally transparent to users except for the following:

- The `wsOption` is not supported in browsers.
- Browsers doesn't allow to catch many WebSocket errors for [security reasons](https://stackoverflow.com/a/31003057) as:

  > Access to this information could allow a malicious Web page to gain information about your network, so they require browsers report all connection-time errors in an indistinguishable way.

  So listening for `client.on('error')` may not catch all the errors you would get in NodeJS env.

### Bundle

MQTT.js is bundled using [esbuild](https://esbuild.github.io/). It is tested working with all bundlers like Webpack, Vite and React.

You can find all mqtt bundles versions in `dist` folder:

- `mqtt.js` - iife format, not minified
- `mqtt.min.js` - iife format, minified
- `mqtt.esm.js` - esm format minified

Starting from MQTT.js > 5.2.0 you can import mqtt in your code like this:

```js
import mqtt from 'mqtt'
```

This will be automatically handled by your bundler.

Otherwise you can choose to use a specific bundle like:

```js
import * as mqtt from 'mqtt/dist/mqtt'
import * as mqtt from 'mqtt/dist/mqtt.min'
import mqtt from 'mqtt/dist/mqtt.esm'
```

<a name="cdn"></a>

### Via CDN

The MQTT.js bundle is available through <http://unpkg.com>, specifically
at <https://unpkg.com/mqtt/dist/mqtt.min.js>.
See <http://unpkg.com> for the full documentation on version ranges.

<a name="qos"></a>

## About QoS

Here is how QoS works:

- QoS 0 : received **at most once** : The packet is sent, and that's it. There is no validation about whether it has been received.
- QoS 1 : received **at least once** : The packet is sent and stored as long as the client has not received a confirmation from the server. MQTT ensures that it _will_ be received, but there can be duplicates.
- QoS 2 : received **exactly once** : Same as QoS 1 but there is no duplicates.

About data consumption, obviously, QoS 2 > QoS 1 > QoS 0, if that's a concern to you.

<a name="typescript"></a>

## Usage with TypeScript

Starting from v5 this project is written in TypeScript and the type definitions are included in the package.

Example:

```ts
import { connect } from "mqtt"
const client = connect('mqtt://test.mosquitto.org')
```

<a name="weapp-alipay"></a>

## WeChat and Ali Mini Program support

### WeChat Mini Program

Supports [WeChat Mini Program](https://mp.weixin.qq.com/). Use the `wxs` protocol. See [the WeChat docs](https://mp.weixin.qq.com/debug/wxadoc/dev/api/network-socket.html).

```js
import 'abortcontroller-polyfill/dist/abortcontroller-polyfill-only' // import before mqtt.
import 'esbuild-plugin-polyfill-node/polyfills/navigator'
const mqtt = require("mqtt");
const client = mqtt.connect("wxs://test.mosquitto.org", {
  timerVariant: 'native' // more info ref issue: #1797
});
```

### Ali Mini Program

Supports [Ali Mini Program](https://open.alipay.com/channel/miniIndex.htm). Use the `alis` protocol. See [the Alipay docs](https://docs.alipay.com/mini/developer/getting-started).
<a name="example"></a>

```js
const mqtt = require("mqtt");
const client = mqtt.connect("alis://test.mosquitto.org");
```

<a name="contributing"></a>

## Contributing

MQTT.js is an **OPEN Open Source Project**. This means that:

> Individuals making significant and valuable contributions are given commit-access to the project to contribute as they see fit. This project is more like an open wiki than a standard guarded open source project.

See the [CONTRIBUTING.md](https://github.com/mqttjs/MQTT.js/blob/master/CONTRIBUTING.md) file for more details.

### Contributors

MQTT.js is only possible due to the excellent work of the following contributors:

| Name               | GitHub                                             | Twitter                                                    |
| ------------------ | -------------------------------------------------- | ---------------------------------------------------------- |
| Adam Rudd          | [GitHub/adamvr](https://github.com/adamvr)         | [Twitter/@adam_vr](http://twitter.com/adam_vr)             |
| Matteo Collina     | [GitHub/mcollina](https://github.com/mcollina)     | [Twitter/@matteocollina](http://twitter.com/matteocollina) |
| Maxime Agor        | [GitHub/4rzael](https://github.com/4rzael)         | [Twitter/@4rzael](http://twitter.com/4rzael)               |
| Siarhei Buntsevich | [GitHub/scarry1992](https://github.com/scarry1992) |                                                            |
| Daniel Lando    | [GitHub/robertsLando](https://github.com/robertsLando) |                                                           |

<a name="sponsor"></a>

## Sponsor

If you would like to support MQTT.js, please consider sponsoring the author and active maintainers:

- [Matteo Collina](https://github.com/sponsors/mcollina): author of MQTT.js
- [Daniel Lando](https://github.com/sponsors/robertsLando): active maintainer

<a name="license"></a>

## License

MIT


================================================
FILE: benchmarks/bombing.js
================================================
#! /usr/bin/env node

const mqtt = require('..')

const client = mqtt.connect({
	port: 1883,
	host: 'localhost',
	clean: true,
	keepalive: 0,
})

let sent = 0
const interval = 5000

function count() {
	console.log('sent/s', (sent / interval) * 1000)
	sent = 0
}

setInterval(count, interval)

function publish() {
	sent++
	client.publish('test', 'payload', publish)
}

client.on('connect', publish)

client.on('error', () => {
	console.log('reconnect!')
	client.stream.end()
})


================================================
FILE: benchmarks/throughputCounter.js
================================================
#! /usr/bin/env node

const mqtt = require('..')

const client = mqtt.connect({
	port: 1883,
	host: 'localhost',
	clean: true,
	encoding: 'binary',
	keepalive: 0,
})
let counter = 0
const interval = 5000

function count() {
	console.log('received/s', (counter / interval) * 1000)
	counter = 0
}

setInterval(count, interval)

client.on('connect', () => {
	count()
	this.subscribe('test')
	this.on('message', () => {
		counter++
	})
})


================================================
FILE: electron-test/.gitignore
================================================
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock
.DS_Store

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# TypeScript v1 declaration files
typings/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env
.env.test

# parcel-bundler cache (https://parceljs.org/)
.cache

# next.js build output
.next

# nuxt.js build output
.nuxt

# vuepress build output
.vuepress/dist

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# Webpack
.webpack/

# Vite
.vite/

# Electron-Forge
out/


================================================
FILE: electron-test/README
================================================
```
npm i
npm run wdio
```


================================================
FILE: electron-test/forge.config.js
================================================
const { FusesPlugin } = require('@electron-forge/plugin-fuses');
const { FuseV1Options, FuseVersion } = require('@electron/fuses');

module.exports = {
  packagerConfig: {
    asar: true,
  },
  rebuildConfig: {},
  makers: [
    {
      name: '@electron-forge/maker-zip',
      platforms: ['linux'],
    },
  ],
  plugins: [
    {
      name: '@electron-forge/plugin-auto-unpack-natives',
      config: {},
    },
    // Fuses are used to enable/disable various Electron functionality
    // at package time, before code signing the application
    new FusesPlugin({
      version: FuseVersion.V1,
      [FuseV1Options.RunAsNode]: false,
      [FuseV1Options.EnableCookieEncryption]: true,
      [FuseV1Options.EnableNodeOptionsEnvironmentVariable]: false,
      [FuseV1Options.EnableNodeCliInspectArguments]: false,
      [FuseV1Options.EnableEmbeddedAsarIntegrityValidation]: true,
      [FuseV1Options.OnlyLoadAppFromAsar]: true,
    }),
  ],
};


================================================
FILE: electron-test/package.json
================================================
{
  "name": "electron-test",
  "productName": "electron-test",
  "version": "1.0.0",
  "description": "My Electron application description",
  "main": "src/index.js",
  "scripts": {
    "start": "electron-forge start",
    "package": "electron-forge package",
    "make": "electron-forge make",
    "publish": "electron-forge publish",
    "lint": "echo \"No linting configured\"",
    "wdio": "npm run package && wdio run ./wdio.conf.ts"
  },
  "devDependencies": {
    "@electron-forge/cli": "7.6.1",
    "@electron-forge/maker-zip": "7.6.1",
    "@electron-forge/plugin-auto-unpack-natives": "7.6.1",
    "@electron-forge/plugin-fuses": "7.6.1",
    "@electron/fuses": "1.8.0",
    "@wdio/cli": "9.9.1",
    "@wdio/local-runner": "9.9.1",
    "@wdio/mocha-framework": "9.9.0",
    "@wdio/spec-reporter": "9.9.0",
    "aedes-cli": "0.8.0",
    "electron": "34.2.0",
    "typescript": "^5.4.5",
    "wdio-electron-service": "8.0.0"
  },
  "keywords": [],
  "author": {
    "name": "axi92"
  },
  "license": "MIT",
  "dependencies": {
    "jquery": "3.7.1"
  }
}


================================================
FILE: electron-test/src/index.css
================================================
body {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica,
    Arial, sans-serif;
  margin: auto;
  max-width: 38rem;
  padding: 2rem;
}


================================================
FILE: electron-test/src/index.html
================================================
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello World!</title>
    <link rel="stylesheet" href="index.css" />
  </head>
  <body>
    <h1>💖 Hello World!</h1>
    <p>Welcome to your Electron application.</p>
    Mqtt connection status: <a id="status">offline</a><br>
    Protocol: <a id="protocol"></a>
  </body>
  <script>
    require('./renderer.js');
  </script>
</html>


================================================
FILE: electron-test/src/index.js
================================================
const { app, BrowserWindow } = require('electron');
const path = require('node:path');

const createWindow = () => {
	// Create the browser window.
	const mainWindow = new BrowserWindow({
		width: 800,
		height: 600,
		show: true,
		webPreferences: {
			sandbox: false,
			nodeIntegration: true,
			contextIsolation: false,
		},
	});

	// and load the index.html of the app.
	mainWindow.loadFile(path.join(__dirname, 'index.html'));

	// Open the DevTools.
	// mainWindow.webContents.openDevTools();
};

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
	createWindow();

	// On OS X it's common to re-create a window in the app when the
	// dock icon is clicked and there are no other windows open.
	app.on('activate', () => {
		if (BrowserWindow.getAllWindows().length === 0) {
			createWindow();
		}
	});
});

// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
	if (process.platform !== 'darwin') {
		app.quit();
	}
});


================================================
FILE: electron-test/src/renderer.js
================================================
window.$ = window.jQuery = require('jquery')
const path = require('node:path');
const mqtt = require(path.join(process.cwd(), '../build/mqtt'))

console.log('start connecting...')
const client = mqtt.connect({
  protocol: 'mqtt',
  port: 1883,
})

client.on('connect', () => {
  $('#status').text('online')
  $('#protocol').text(client.options.protocol)
})


================================================
FILE: electron-test/test/service/server_launcher.ts
================================================
import type { Services } from '@wdio/types'
import { resolve as pathResolve } from 'path'
const { start } = require('aedes-cli')


export default class ServerLauncher implements Services.ServiceInstance {

    #aedesBroker: any

    constructor() {
        this.#aedesBroker = null
    }

    async onPrepare(): Promise<void> {
        const keyPath = pathResolve(__dirname, '../../../test/browser/certs/server-key.pem')
        const certPath = pathResolve(__dirname, '../../../test/browser/certs/server-cert.pem')

        this.#aedesBroker = await start({
            protos: ['tcp', 'tls'],
            port: 1883,
            tlsPort: 8883,
            key: keyPath,
            cert: certPath,
            verbose: true,
            stats: false,
        })
    }

    async onComplete(): Promise<void> {
        if (!this.#aedesBroker?.servers) {
            return
        }

        for (const server of this.#aedesBroker.servers) {
            if (server.listening) {
                await new Promise<void>((resolve, reject) => {
                    server.close((err: any) => {
                        if (err)
                            reject(err)
                        else
                            resolve()
                    })
                })
            }
        }
    }
}

================================================
FILE: electron-test/test/specs/test.e2e.ts
================================================
import { expect, $ } from '@wdio/globals'
// import { join } from 'path'
import isBrowser from '../../../build/lib/is-browser'
// import isBrowser from join(process.cwd(), '../build/lib/is-browser')

describe('Electron Testing', () => {
    it('should render electron window', async () => {
        await expect($('h1')).toHaveText('💖 Hello World!')
    })

    it('should connect', async() => {
      await expect($('#status')).toHaveText('online')
    })

    it('should not be a browser context', async() =>{
      expect(isBrowser).toBe(false)
    })

    it('should use protocoll mqtt', async() => {
      await expect($('#protocol')).toHaveText('mqtt')
    })
})



================================================
FILE: electron-test/tsconfig.json
================================================
{
    "compilerOptions": {
        "moduleResolution": "node",
        "module": "commonjs",
        "target": "es2022",
        "lib": [
            "es2022",
            "dom"
        ],
        "types": [
            "node",
            "@wdio/globals/types",
            "expect-webdriverio",
            "@wdio/mocha-framework",
            "wdio-electron-service"
        ],
        "skipLibCheck": true,
        "noEmit": true,
        "allowImportingTsExtensions": true,
        "resolveJsonModule": true,
        "isolatedModules": true,
        "strict": true,
        "noUnusedLocals": true,
        "noUnusedParameters": true,
        "noFallthroughCasesInSwitch": true
    },
    "include": [
        "test",
        "wdio.conf.ts"
    ]
}

================================================
FILE: electron-test/wdio.conf.ts
================================================
import { resolve as pathResolve } from 'node:path';
import ServerLauncher from './test/service/server_launcher'

const electronAppBinaryPath = pathResolve('./out/electron-test-linux-x64/electron-test');

export const config: WebdriverIO.Config = {
    //
    // ====================
    // Runner Configuration
    // ====================
    // WebdriverIO supports running e2e tests as well as unit and component tests.
    runner: 'local',
    tsConfigPath: './tsconfig.json',

    //
    // ==================
    // Specify Test Files
    // ==================
    // Define which test specs should run. The pattern is relative to the directory
    // of the configuration file being run.
    //
    // The specs are defined as an array of spec files (optionally using wildcards
    // that will be expanded). The test for each spec file will be run in a separate
    // worker process. In order to have a group of spec files run in the same worker
    // process simply enclose them in an array within the specs array.
    //
    // The path of the spec files will be resolved relative from the directory of
    // of the config file unless it's absolute.
    //
    specs: [
        './test/specs/**/*.ts'
    ],
    // Patterns to exclude.
    exclude: [
        // 'path/to/excluded/files'
    ],
    //
    // ============
    // Capabilities
    // ============
    // Define your capabilities here. WebdriverIO can run multiple capabilities at the same
    // time. Depending on the number of capabilities, WebdriverIO launches several test
    // sessions. Within your capabilities you can overwrite the spec and exclude options in
    // order to group specific specs to a specific capability.
    //
    // First, you can define how many instances should be started at the same time. Let's
    // say you have 3 different capabilities (Chrome, Firefox, and Safari) and you have
    // set maxInstances to 1; wdio will spawn 3 processes. Therefore, if you have 10 spec
    // files and you set maxInstances to 10, all spec files will get tested at the same time
    // and 30 processes will get spawned. The property handles how many capabilities
    // from the same test should run tests.
    //
    maxInstances: 10,
    //
    // If you have trouble getting all important capabilities together, check out the
    // Sauce Labs platform configurator - a great tool to configure your capabilities:
    // https://saucelabs.com/platform/platform-configurator
    //
    capabilities: [{
        browserName: 'electron',
        // Electron service options
        // see https://webdriver.io/docs/desktop-testing/electron/configuration/#service-options
        'wdio:electronServiceOptions': {
            appBinaryPath: electronAppBinaryPath,
        }
    }],

    //
    // ===================
    // Test Configurations
    // ===================
    // Define all options that are relevant for the WebdriverIO instance here
    //
    // Level of logging verbosity: trace | debug | info | warn | error | silent
    logLevel: 'info',
    //
    // Set specific log levels per logger
    // loggers:
    // - webdriver, webdriverio
    // - @wdio/browserstack-service, @wdio/lighthouse-service, @wdio/sauce-service
    // - @wdio/mocha-framework, @wdio/jasmine-framework
    // - @wdio/local-runner
    // - @wdio/sumologic-reporter
    // - @wdio/cli, @wdio/config, @wdio/utils
    // Level of logging verbosity: trace | debug | info | warn | error | silent
    // logLevels: {
    //     webdriver: 'info',
    //     '@wdio/appium-service': 'info'
    // },
    //
    // If you only want to run your tests until a specific amount of tests have failed use
    // bail (default is 0 - don't bail, run all tests).
    bail: 0,
    //
    // Set a base URL in order to shorten url command calls. If your `url` parameter starts
    // with `/`, the base url gets prepended, not including the path portion of your baseUrl.
    // If your `url` parameter starts without a scheme or `/` (like `some/path`), the base url
    // gets prepended directly.
    // baseUrl: 'http://localhost:8080',
    //
    // Default timeout for all waitFor* commands.
    waitforTimeout: 10000,
    //
    // Default timeout in milliseconds for request
    // if browser driver or grid doesn't send response
    connectionRetryTimeout: 120000,
    //
    // Default request retries count
    connectionRetryCount: 3,
    //
    // Test runner services
    // Services take over a specific job you don't want to take care of. They enhance
    // your test setup with almost no effort. Unlike plugins, they don't add new
    // commands. Instead, they hook themselves up into the test process.
    services: [
        [ServerLauncher, {}],
        'electron',
    ],

    // Framework you want to run your specs with.
    // The following are supported: Mocha, Jasmine, and Cucumber
    // see also: https://webdriver.io/docs/frameworks
    //
    // Make sure you have the wdio adapter package for the specific framework installed
    // before running any tests.
    framework: 'mocha',

    //
    // The number of times to retry the entire specfile when it fails as a whole
    // specFileRetries: 1,
    //
    // Delay in seconds between the spec file retry attempts
    // specFileRetriesDelay: 0,
    //
    // Whether or not retried spec files should be retried immediately or deferred to the end of the queue
    // specFileRetriesDeferred: false,
    //
    // Test reporter for stdout.
    // The only one supported by default is 'dot'
    // see also: https://webdriver.io/docs/dot-reporter
    reporters: ['spec'],

    // Options to be passed to Mocha.
    // See the full list at http://mochajs.org/
    mochaOpts: {
        ui: 'bdd',
        timeout: 60000
    },

    //
    // =====
    // Hooks
    // =====
    // WebdriverIO provides several hooks you can use to interfere with the test process in order to enhance
    // it and to build services around it. You can either apply a single function or an array of
    // methods to it. If one of them returns with a promise, WebdriverIO will wait until that promise got
    // resolved to continue.
    /**
     * Gets executed once before all workers get launched.
     * @param {object} config wdio configuration object
     * @param {Array.<Object>} capabilities list of capabilities details
     */
    // onPrepare: function (config, capabilities) {
    // },
    /**
     * Gets executed before a worker process is spawned and can be used to initialize specific service
     * for that worker as well as modify runtime environments in an async fashion.
     * @param  {string} cid      capability id (e.g 0-0)
     * @param  {object} caps     object containing capabilities for session that will be spawn in the worker
     * @param  {object} specs    specs to be run in the worker process
     * @param  {object} args     object that will be merged with the main configuration once worker is initialized
     * @param  {object} execArgv list of string arguments passed to the worker process
     */
    // onWorkerStart: function (cid, caps, specs, args, execArgv) {
    // },
    /**
     * Gets executed just after a worker process has exited.
     * @param  {string} cid      capability id (e.g 0-0)
     * @param  {number} exitCode 0 - success, 1 - fail
     * @param  {object} specs    specs to be run in the worker process
     * @param  {number} retries  number of retries used
     */
    // onWorkerEnd: function (cid, exitCode, specs, retries) {
    // },
    /**
     * Gets executed just before initialising the webdriver session and test framework. It allows you
     * to manipulate configurations depending on the capability or spec.
     * @param {object} config wdio configuration object
     * @param {Array.<Object>} capabilities list of capabilities details
     * @param {Array.<String>} specs List of spec file paths that are to be run
     * @param {string} cid worker id (e.g. 0-0)
     */
    // beforeSession: function (config, capabilities, specs, cid) {
    // },
    /**
     * Gets executed before test execution begins. At this point you can access to all global
     * variables like `browser`. It is the perfect place to define custom commands.
     * @param {Array.<Object>} capabilities list of capabilities details
     * @param {Array.<String>} specs        List of spec file paths that are to be run
     * @param {object}         browser      instance of created browser/device session
     */
    // before: function (capabilities, specs) {
    // },
    /**
     * Runs before a WebdriverIO command gets executed.
     * @param {string} commandName hook command name
     * @param {Array} args arguments that command would receive
     */
    // beforeCommand: function (commandName, args) {
    // },
    /**
     * Hook that gets executed before the suite starts
     * @param {object} suite suite details
     */
    // beforeSuite: function (suite) {
    // },
    /**
     * Function to be executed before a test (in Mocha/Jasmine) starts.
     */
    // beforeTest: function (test, context) {
    // },
    /**
     * Hook that gets executed _before_ a hook within the suite starts (e.g. runs before calling
     * beforeEach in Mocha)
     */
    // beforeHook: function (test, context, hookName) {
    // },
    /**
     * Hook that gets executed _after_ a hook within the suite starts (e.g. runs after calling
     * afterEach in Mocha)
     */
    // afterHook: function (test, context, { error, result, duration, passed, retries }, hookName) {
    // },
    /**
     * Function to be executed after a test (in Mocha/Jasmine only)
     * @param {object}  test             test object
     * @param {object}  context          scope object the test was executed with
     * @param {Error}   result.error     error object in case the test fails, otherwise `undefined`
     * @param {*}       result.result    return object of test function
     * @param {number}  result.duration  duration of test
     * @param {boolean} result.passed    true if test has passed, otherwise false
     * @param {object}  result.retries   information about spec related retries, e.g. `{ attempts: 0, limit: 0 }`
     */
    // afterTest: function(test, context, { error, result, duration, passed, retries }) {
    // },


    /**
     * Hook that gets executed after the suite has ended
     * @param {object} suite suite details
     */
    // afterSuite: function (suite) {
    // },
    /**
     * Runs after a WebdriverIO command gets executed
     * @param {string} commandName hook command name
     * @param {Array} args arguments that command would receive
     * @param {number} result 0 - command success, 1 - command error
     * @param {object} error error object if any
     */
    // afterCommand: function (commandName, args, result, error) {
    // },
    /**
     * Gets executed after all tests are done. You still have access to all global variables from
     * the test.
     * @param {number} result 0 - test pass, 1 - test fail
     * @param {Array.<Object>} capabilities list of capabilities details
     * @param {Array.<String>} specs List of spec file paths that ran
     */
    // after: function (result, capabilities, specs) {
    // },
    /**
     * Gets executed right after terminating the webdriver session.
     * @param {object} config wdio configuration object
     * @param {Array.<Object>} capabilities list of capabilities details
     * @param {Array.<String>} specs List of spec file paths that ran
     */
    // afterSession: function (config, capabilities, specs) {
    // },
    /**
     * Gets executed after all workers got shut down and the process is about to exit. An error
     * thrown in the onComplete hook will result in the test run failing.
     * @param {object} exitCode 0 - success, 1 - fail
     * @param {object} config wdio configuration object
     * @param {Array.<Object>} capabilities list of capabilities details
     * @param {<Object>} results object containing test results
     */
    // onComplete: function(exitCode, config, capabilities, results) {
    // },
    /**
    * Gets executed when a refresh happens.
    * @param {string} oldSessionId session ID of the old session
    * @param {string} newSessionId session ID of the new session
    */
    // onReload: function(oldSessionId, newSessionId) {
    // }
    /**
    * Hook that gets executed before a WebdriverIO assertion happens.
    * @param {object} params information about the assertion to be executed
    */
    // beforeAssertion: function(params) {
    // }
    /**
    * Hook that gets executed after a WebdriverIO assertion happened.
    * @param {object} params information about the assertion that was executed, including its results
    */
    // afterAssertion: function(params) {
    // }
}


================================================
FILE: esbuild.js
================================================
const { build } = require('esbuild')
const { polyfillNode } = require('esbuild-plugin-polyfill-node');
const { rimraf } = require('rimraf')
const fs = require('fs')
const { version } = require('./package.json');

const outdir = 'dist'

/**
 * @type {import('esbuild').BuildOptions}
 */
const options = {
    entryPoints: ['build/index.js'],
    bundle: true,
    outfile: `${outdir}/mqtt.js`,
    format: 'iife',
    platform: 'browser',
    globalName: 'mqtt',
    sourcemap: false, // this can be enabled while debugging, if we decide to keep this enabled we should also ship the `src` folder to npm
    plugins: [
        polyfillNode({
            polyfills: [
                'readable-stream'
            ]
        }),
        {
            name: 'resolve-package-json',
            setup(build) {
                // when importing 'package.json' we want to provide a custom object like { version: '1.2.3' }

                build.onResolve({ filter: /package\.json$/ }, args => {
                    return {
                        path: args.path,
                        namespace: 'package-json'
                    }
                })

                build.onLoad({ filter: /.*/, namespace: 'package-json' }, args => {
                    return {
                        contents: JSON.stringify({ version }),
                        loader: 'json'
                    }
                }
                )
            }
        },
        {
            name: 'resolve-socks',
            setup(build) {
                // socks is not supported in the browser and adds several 100kb to the build, so stub it
                build.onResolve({ filter: /socks$/ }, args => {
                    return {
                        path: args.path,
                        namespace: 'socks-stub'
                    }
                })

                build.onLoad({ filter: /.*/, namespace: 'socks-stub' }, args => {
                    return {
                        contents: 'module.exports = {}',
                        loader: 'js'
                    }
                }
                )
            }
        },
    ],
}

async function run() {
    const start = Date.now()
    await rimraf(outdir)
    await build(options)

    options.minify = true
    options.outfile = `${outdir}/mqtt.min.js`
    await build(options)


    options.outfile = `${outdir}/mqtt.esm.js`
    options.format = 'esm'

    await build(options)

    console.log(`Build time: ${Date.now() - start}ms`)
    console.log('Build output:')

    // log generated files with their size in KB
    const files = fs.readdirSync(outdir)
    for (const file of files) {
        const stat = fs.statSync(`${outdir}/${file}`)
        console.log(`- ${file} ${Math.round(stat.size / 1024 * 100) / 100} KB`)
    }
}

run().catch((e) => {
    console.error(e)
    process.exit(1)
})

================================================
FILE: eslint.config.js
================================================
const {
    defineConfig,
    globalIgnores,
} = require("eslint/config");

const tsParser = require("@typescript-eslint/parser");
const typescriptEslintEslintPlugin = require("@typescript-eslint/eslint-plugin");
const globals = require("globals");
const js = require("@eslint/js");

const {
    FlatCompat,
} = require("@eslint/eslintrc");

const compat = new FlatCompat({
    baseDirectory: __dirname,
    recommendedConfig: js.configs.recommended,
    allConfig: js.configs.all
});

module.exports = defineConfig([{
    languageOptions: {
        parser: tsParser,

        globals: {
            ...globals.browser,
            ...globals.commonjs,
            ...globals.node,
            ...globals.worker,
        },

        sourceType: "module",

        parserOptions: {
            project: "tsconfig.json",
            tsconfigRootDir: __dirname,
        },
    },

    plugins: {
        "@typescript-eslint": typescriptEslintEslintPlugin,
    },

    extends: compat.extends("plugin:prettier/recommended", "plugin:@typescript-eslint/recommended"),

    rules: {
        "global-require": "off",
        "no-console": process.env.NODE_ENV === "production" ? "warn" : "off",

        "no-unused-vars": ["error", {
            args: "none",
        }],

        "no-underscore-dangle": "off",
        "no-param-reassign": "off",
        "no-restricted-syntax": "off",
        "default-case": "off",
        "consistent-return": "off",
        "max-classes-per-file": "off",
        "no-plusplus": "off",
        "no-bitwise": "off",
        "class-methods-use-this": "off",
        "no-continue": "off",
        "@typescript-eslint/no-explicit-any": "off",

        "@typescript-eslint/no-unused-vars": ["error", {
            args: "none",
        }],

        "@typescript-eslint/naming-convention": "off",
        "@typescript-eslint/dot-notation": "off",
        "@typescript-eslint/no-use-before-define": "off",

        "@typescript-eslint/consistent-type-imports": ["error", {
            "prefer": "type-imports",
            "fixStyle": "inline-type-imports",
            "disallowTypeAnnotations": true,
        }],
    },
}, globalIgnores([
    "types/",
    "examples/",
    "doc/",
    "dist/",
    "build/",
    "electron-test/",
    "**/*.js",
    "**/*.mjs",
])]);


================================================
FILE: example.ts
================================================
import mqtt from './src/index'

const client = mqtt.connect('mqtt://broker.hivemq.com', {
	keepalive: 3,
	port: 1883,
	reconnectPeriod: 15000,
	rejectUnauthorized: false,
})

const randomNumber = Math.floor(Math.random() * 1000)

const testTopic = `presence_${randomNumber.toString()}`

function publish() {
	const msg = `Hello mqtt ${new Date().toISOString()}`
	client.publish(testTopic, msg, { qos: 1 }, (err2) => {
		if (!err2) {
			console.log('message published')
		} else {
			console.error(err2)
		}
	})
}

client.subscribe(testTopic, (err) => {
	if (!err) {
		console.log('subscribed to', testTopic)
	} else {
		console.error(err)
	}
})

client.on('message', (topic, message) => {
	console.log('received message "%s" from topic "%s"', message, topic)
})

setInterval(() => {
	publish()
}, 2000)

client.on('error', (err) => {
	console.error(err)
})

client.on('connect', () => {
	console.log('connected')
	publish()
})

client.on('disconnect', () => {
	console.log('disconnected')
})

client.on('offline', () => {
	console.log('offline')
})

client.on('reconnect', () => {
	console.log('reconnect')
})


================================================
FILE: examples/client/secure-client.js
================================================
'use strict'

const mqtt = require('../..')
const path = require('path')
const fs = require('fs')
const KEY = fs.readFileSync(path.join(__dirname, '..', '..', 'test', 'helpers', 'tls-key.pem'))
const CERT = fs.readFileSync(path.join(__dirname, '..', '..', 'test', 'helpers', 'tls-cert.pem'))

const PORT = 8443

const options = {
  port: PORT,
  key: KEY,
  cert: CERT,
  rejectUnauthorized: false
}

const client = mqtt.connect(options)

client.subscribe('messages')
client.publish('messages', 'Current time is: ' + new Date())
client.on('message', function (topic, message) {
  console.log(message)
})


================================================
FILE: examples/client/simple-both.js
================================================
'use strict'

const mqtt = require('../..')
const client = mqtt.connect()

// or const client = mqtt.connect({ port: 1883, host: '192.168.1.100', keepalive: 10000});

client.subscribe('presence')
client.publish('presence', 'bin hier')
client.on('message', function (topic, message) {
  console.log(message)
})
client.end()


================================================
FILE: examples/client/simple-publish.js
================================================
'use strict'

const mqtt = require('../..')
const client = mqtt.connect()

client.publish('presence', 'hello!')
client.end()


================================================
FILE: examples/client/simple-subscribe.js
================================================
'use strict'

const mqtt = require('../..')
const client = mqtt.connect()

client.subscribe('presence')
client.on('message', function (topic, message) {
  console.log(message)
})


================================================
FILE: examples/tls client/crt.ca.cg.pem
================================================
-----BEGIN CERTIFICATE-----
MIIF7zCCA9egAwIBAgIJAOeJR1p1PU3qMA0GCSqGSIb3DQEBBQUAMIGNMQswCQYD
VQQGEwJFUzERMA8GA1UECAwIWmFyYWdvemExETAPBgNVBAcMCFphcmFnb3phMRkw
FwYDVQQKDBBNUVRUIGZvciBub2RlLmpzMRAwDgYDVQQLDAdNUVRULmpzMQ0wCwYD
VQQDDARtcXR0MRwwGgYJKoZIhvcNAQkBFg1mYWtlQG1haWwuY29tMB4XDTEzMDgz
MDEzMDIwNVoXDTIzMDgyODEzMDIwNVowgY0xCzAJBgNVBAYTAkVTMREwDwYDVQQI
DAhaYXJhZ296YTERMA8GA1UEBwwIWmFyYWdvemExGTAXBgNVBAoMEE1RVFQgZm9y
IG5vZGUuanMxEDAOBgNVBAsMB01RVFQuanMxDTALBgNVBAMMBG1xdHQxHDAaBgkq
hkiG9w0BCQEWDWZha2VAbWFpbC5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
ggIKAoICAQC7Of6OppOE+xwPdPcsT0w3keCa5k4ufZCqUAHex7+mLlrpjfCjQ2z6
Rm0XBiCu9vy+xvLtbGDh5e/gocjAkkEywjbtrRMiFq5i41BNT3dzEWb9cCXvMWYa
RxQgIqouJUz5r+TbaP1bm4gAWTHmp09ccoIs9Tykxhyc1nZxXVrEsHF4aBmuw5NJ
ZwxK1tJTgP4m5H38Ms7ahGpByPsnMg6GBRs/Yen0mGhOsG+MU4TFiQb4bwIxg8Eu
ntGP1gARvtmyTkkTDhfksRs+muEV17uPtdhGNS/0CGRWaZ2mjEYyD70Ijl2grLd4
6Vz27uPaqUvbgntPNadKqFN+jEHTtptou3k6V9C8CeLHIq+5N6abfPVHBzaqyNqg
QelzpSgQQBJ1H0CYREjzAs9uLfeep5ejW99Ik4YwtL6UrTVUyGzGgAl9mevZN5a4
7mEY7MNUFdwigq0ZpbZmzYiuOURGYnoiy5o64balG5XH6Zh6B1WWhK7CArPVosz8
eoQacj1WEM5d2Ivg1OLlEdD8FZDABv5CMTmRvnoFQuuIDzWVfrhdcZQ2tQuNLWrz
YDKheCunPkAIFOlGi70Xv3DVrTCr6kixwL2p9MHTzF4xiWWtiOv41ZXHTMG0t2I3
YmA45FEO5JawebPgUoGhoc2vgIw5Jo9dcGtwLCqBHSnCojPoTipVhQIDAQABo1Aw
TjAdBgNVHQ4EFgQU1yVv/ezoDLs+qjbx0O4KiHpC41swHwYDVR0jBBgwFoAU1yVv
/ezoDLs+qjbx0O4KiHpC41swDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOC
AgEAScnfOewEk59DgfICJJ2vhcI33wqqn54zhJ1pi8SX3e7PLv26UEUXZaddIqeZ
JzA/IWF+GCBQFAL7Z+sI4djXx/UpZp5ptCQBFc0tinHk1CGlC0E+LI3JS/cnFf+2
L8VKZHbSf4ua2f/VMJo7uoyrw/gQHgUToAlYYWpGcIKKm7d0JYQE60wlHk9TXgCc
s9XAwI+bP9VKNQkZCeooODG/5VcxdJafZSU3rW1WniFcD/R+ZNq7FZYbM+2u2mRt
Qm7Hh/FjrN4Hnmf3xdNUE0NLHznwk4CD6EeQukN12yP2ccubnG6Z7HFFdV0g9fEP
AVMsgY/9E9Te/BBoQKjhIg8c274ozIOsCHODx15Mn52848sq0LIQjyeOH4rtuWLL
1dFE1ysY2gzSMUtrP+on+r6F1GkndFszxfDrBcZMXs85VAy3eKfY/jzUMrdfn0YJ
36Wz7F40vnOUd2ni24kaOfnRodbu3lOEYD6l5fDGP79kfITyy+dtL6ExTLZQmEn+
xKsWM9bBkV4STpFiTF61tJwzlcAL1ZDLqDaSwsM8UDZopnDgvklNoJK9XzdLwD1X
PofOtUe08G4tq5cBDVURLKif+7EfCyAqvUptQ3MJarhoXzhDy9CjtN8TmWexKC1q
kB5DBML0Y4NnqTEnfYCs/XFPosaS+0GximGySJcg08ay6ZA=
-----END CERTIFICATE-----


================================================
FILE: examples/tls client/mqttclient.js
================================================
'use strict'

/** ************************** IMPORTANT NOTE ***********************************

  The certificate used on this example has been generated for a host named stark.
  So as host we SHOULD use stark if we want the server to be authorized.
  For testing this we should add on the computer running this example a line on
  the hosts file:
  /etc/hosts [UNIX]
  OR
  \System32\drivers\etc\hosts [Windows]

  The line to add on the file should be as follows:
  <the ip address of the server> stark
 *******************************************************************************/

const mqtt = require('mqtt')
const fs = require('fs')
const path = require('path')
const KEY = fs.readFileSync(path.join(__dirname, '/tls-key.pem'))
const CERT = fs.readFileSync(path.join(__dirname, '/tls-cert.pem'))
const TRUSTED_CA_LIST = fs.readFileSync(path.join(__dirname, '/crt.ca.cg.pem'))

const PORT = 1883
const HOST = 'stark'

const options = {
  port: PORT,
  host: HOST,
  key: KEY,
  cert: CERT,
  rejectUnauthorized: true,
  // The CA list will be used to determine if server is authorized
  ca: TRUSTED_CA_LIST,
  protocol: 'mqtts'
}

const client = mqtt.connect(options)

client.subscribe('messages')
client.publish('messages', 'Current time is: ' + new Date())
client.on('message', (topic, message) => {
  console.log(message)
})

client.on('connect', () => {
  console.log('Connected')
})


================================================
FILE: examples/tls client/tls-cert.pem
================================================
-----BEGIN CERTIFICATE-----
MIICATCCAWoCCQC2pNY4sfld/jANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJB
VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
cyBQdHkgTHRkMB4XDTEzMDgyNzEyNTU0NVoXDTEzMDkyNjEyNTU0NVowRTELMAkG
A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0
IFdpZGdpdHMgUHR5IEx0ZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAzXGU
1mZUBqLwoP1fWkiZeypiKgWICUdNm+d2JHXnpQMEVBxSvsaRGOnzWVvgbMVxmD7n
5/p9qQGTj8FY/+t2NHpbt1I9lGV0+BlZxGJvyvHikEAXPD85EEFhqSbDwgkVuMqa
w08njqhJJ37fbd2ux6w4woRrDTN4r9CNMhFb9QECAwEAATANBgkqhkiG9w0BAQUF
AAOBgQBIlZYo1rf8GlISuV1haSBm8U/uiyjIX/pTE5Cs7Kb84SPzKB0tHnGGCa2t
Lu+TEwetF3NatuI1biqYuevQSfmEM75zsRSwt1P40sJ2y9B1XRTdamHOHCYCJG/b
rti7WJYjvO8JsCUeB6M+5jFodbmvjsGgAHLLUINXrxOqYe+PWg==
-----END CERTIFICATE-----


================================================
FILE: examples/tls client/tls-key.pem
================================================
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDNcZTWZlQGovCg/V9aSJl7KmIqBYgJR02b53YkdeelAwRUHFK+
xpEY6fNZW+BsxXGYPufn+n2pAZOPwVj/63Y0elu3Uj2UZXT4GVnEYm/K8eKQQBc8
PzkQQWGpJsPCCRW4yprDTyeOqEknft9t3a7HrDjChGsNM3iv0I0yEVv1AQIDAQAB
AoGBALv9P+WEE0VTWf7mepdBsXfbi6HKF/Xtkh2kCh5I6WO8Q/y3Qhwh1OnIQg41
nUHK1iwq+8fxFYVN1PoJQWhEzI6JdBCrn88oADo/aVm1mGN5CWr3pwn92SAVMhbw
442AWWG81RStrr2uPhLBNE6U/4P835qM8uG4rCP+5Z5SzX7VAkEA+TptuSc0TEkL
5B/Nml2fYNfbQvRGVzyCbdCXdgkeZt5xuSuwDgC4GvWgjL+SAN1fjTek/Iez5NnL
xHa5w93j2wJBANMGmRTaTxvpGdkUi/utTPtCp6GXL7hS9v41LClmQTYBOYscPn2b
Dny2fyZPp29sZ7+AvXHWZxw7QtH+jO2Xz1MCQCI7vlqSYgKgffulyq4LchrxS3LU
7tyIuTmwTz2tXvmuUFyo/ZPO0XsShi0PG1T3E2roW8c8NJ+Ysv6XeEjJL8UCQG0Z
/S0tzTa15no4SEM/jwxcosRFoRNgOXimTwW8azybl3+Xg6t27h+GTuikyAEwf9cf
nVJssfSDowFk5MG1+icCQQCqBOTXEukcJRXZixkpfEuuvS3RNzOYwG4ReKjpvWPy
EvsfHoCsO1Sz9qz8DXpwl3GEWUGGTfWwBfereX6HLXj+
-----END RSA PRIVATE KEY-----


================================================
FILE: examples/vite-example/.gitignore
================================================
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
.DS_Store
dist
dist-ssr
coverage
*.local

/cypress/videos/
/cypress/screenshots/

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?


================================================
FILE: examples/vite-example/README.md
================================================
# vite-example

This template should help get you started developing with Vue 3 in Vite.

## Recommended IDE Setup

[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).

## Customize configuration

See [Vite Configuration Reference](https://vitejs.dev/config/).

## Project Setup

```sh
npm install
```

### Compile and Hot-Reload for Development

```sh
npm run dev
```

### Compile and Minify for Production

```sh
npm run build
```


================================================
FILE: examples/vite-example/index.html
================================================
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <link rel="icon" href="/favicon.ico">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vite App</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.js"></script>
  </body>
</html>


================================================
FILE: examples/vite-example/package.json
================================================
{
  "name": "vite-example",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "@esbuild-plugins/node-modules-polyfill": "^0.2.2",
    "mqtt": "file:../../",
    "process": "^0.11.10",
    "vue": "^3.3.4"
  },
  "devDependencies": {
    "@esbuild-plugins/node-globals-polyfill": "^0.2.3",
    "@vitejs/plugin-vue": "^4.2.3",
    "rollup-plugin-polyfill-node": "^0.12.0",
    "vite": "^4.5.3"
  }
}


================================================
FILE: examples/vite-example/src/App.vue
================================================
<script setup>
import { ref } from 'vue'
import mqtt from 'mqtt'

const connected = ref(false)

const client = mqtt.connect('wss://test.mosquitto.org:8081', {
  log: console.log.bind(console),
  keepalive: 30,
});

const messages = ref([])

client.on("connect", () => {
  console.log("connected");
  connected.value = true
  client.subscribe("presence", (err) => {
    if (!err) {
      console.log("subscribed");
      client.publish("presence", "Hello mqtt");
    }
  });
});

client.on("message", (topic, message) => {
  console.log('message', topic, message.toString());
  // message is Buffer
  messages.value.push(message.toString());
});

client.on("close", () => {
  console.log("close");
  connected.value = false
});

</script>

<template>
  <main>
    <h1>MQTTjs VITE Example</h1>
    <p>
      MQTTjs is a simple MQTT client for the browser. It uses WebSockets to
      connect to an MQTT broker.
    </p>
    <p>
      This example uses the public MQTT broker at
      <a href="https://test.mosquitto.org/">test.mosquitto.org</a>.
    </p>
    
    <p>Status: {{ connected ? 'Connected' : 'Disconnected' }}</p>
    <p>
      <button @click="client.publish('presence', 'Hello mqtt')">Publish</button>
      <button @click="client.end()">Disconnect</button>
    </p>
    <p>Messages:</p>
    <ul>
      <li v-for="message in messages" :key="message">{{ message }}</li>
    </ul>
    
  </main>
</template>




================================================
FILE: examples/vite-example/src/assets/base.css
================================================
/* color palette from <https://github.com/vuejs/theme> */
:root {
  --vt-c-white: #ffffff;
  --vt-c-white-soft: #f8f8f8;
  --vt-c-white-mute: #f2f2f2;

  --vt-c-black: #181818;
  --vt-c-black-soft: #222222;
  --vt-c-black-mute: #282828;

  --vt-c-indigo: #2c3e50;

  --vt-c-divider-light-1: rgba(60, 60, 60, 0.29);
  --vt-c-divider-light-2: rgba(60, 60, 60, 0.12);
  --vt-c-divider-dark-1: rgba(84, 84, 84, 0.65);
  --vt-c-divider-dark-2: rgba(84, 84, 84, 0.48);

  --vt-c-text-light-1: var(--vt-c-indigo);
  --vt-c-text-light-2: rgba(60, 60, 60, 0.66);
  --vt-c-text-dark-1: var(--vt-c-white);
  --vt-c-text-dark-2: rgba(235, 235, 235, 0.64);
}

/* semantic color variables for this project */
:root {
  --color-background: var(--vt-c-white);
  --color-background-soft: var(--vt-c-white-soft);
  --color-background-mute: var(--vt-c-white-mute);

  --color-border: var(--vt-c-divider-light-2);
  --color-border-hover: var(--vt-c-divider-light-1);

  --color-heading: var(--vt-c-text-light-1);
  --color-text: var(--vt-c-text-light-1);

  --section-gap: 160px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --color-background: var(--vt-c-black);
    --color-background-soft: var(--vt-c-black-soft);
    --color-background-mute: var(--vt-c-black-mute);

    --color-border: var(--vt-c-divider-dark-2);
    --color-border-hover: var(--vt-c-divider-dark-1);

    --color-heading: var(--vt-c-text-dark-1);
    --color-text: var(--vt-c-text-dark-2);
  }
}

*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  font-weight: normal;
}

body {
  min-height: 100vh;
  color: var(--color-text);
  background: var(--color-background);
  transition: color 0.5s, background-color 0.5s;
  line-height: 1.6;
  font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu,
    Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
  font-size: 15px;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}


================================================
FILE: examples/vite-example/src/assets/main.css
================================================
@import './base.css';

#app {
  max-width: 1280px;
  margin: 0 auto;
  padding: 2rem;

  font-weight: normal;
}

a,
.green {
  text-decoration: none;
  color: hsla(160, 100%, 37%, 1);
  transition: 0.4s;
}

@media (hover: hover) {
  a:hover {
    background-color: hsla(160, 100%, 37%, 0.2);
  }
}

@media (min-width: 1024px) {
  body {
    display: flex;
    place-items: center;
  }

  #app {
    display: grid;
    grid-template-columns: 1fr 1fr;
    padding: 0 2rem;
  }
}


================================================
FILE: examples/vite-example/src/main.js
================================================
import './assets/main.css'

import { createApp } from 'vue'
import App from './App.vue'

createApp(App).mount('#app')


================================================
FILE: examples/vite-example/vite.config.js
================================================
import { fileURLToPath, URL } from 'node:url'

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
  ],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url)),
    }
  },
})


================================================
FILE: examples/ws/aedes_server.js
================================================
const aedes = require('aedes')()
const httpServer = require('http').createServer()
const WebSocket = require('ws')
const wsPort = 8080

// Here we are creating the Websocket Server that is using the HTTP Server...
const wss = new WebSocket.Server({ server: httpServer })
wss.on('connection', function connection (ws) {
  const duplex = WebSocket.createWebSocketStream(ws)
  aedes.handle(duplex)
})

httpServer.listen(wsPort, () => {
  console.log('websocket server listening on port', wsPort)
})

aedes.on('clientError', (client, err) => {
  console.log('client error', client.id, err.message, err.stack)
})

aedes.on('connectionError', (client, err) => {
  console.log('client error', client, err.message, err.stack)
})

aedes.on('publish', (packet, client) => {
  if (packet && packet.payload) {
    console.log('publish packet:', packet.payload.toString())
  }
  if (client) {
    console.log('message from client', client.id)
  }
})

aedes.on('subscribe', (subscriptions, client) => {
  if (client) {
    console.log('subscribe from client', subscriptions, client.id)
  }
})

aedes.on('client', (client) => {
  console.log('new client', client.id)
})


================================================
FILE: examples/ws/client.js
================================================
'use strict'

const mqtt = require('../../')

const clientId = 'mqttjs_' + Math.random().toString(16).substr(2, 8)

// This sample should be run in tandem with the aedes_server.js file.
// Simply run it:
// $ node aedes_server.js
//
// Then run this file in a separate console:
// $ node websocket_sample.js
//
const host = 'ws://localhost:8080'

const options = {
  keepalive: 30,
  clientId,
  protocolId: 'MQTT',
  protocolVersion: 4,
  clean: true,
  reconnectPeriod: 1000,
  connectTimeout: 30 * 1000,
  will: {
    topic: 'WillMsg',
    payload: 'Connection Closed abnormally..!',
    qos: 0,
    retain: false
  },
  rejectUnauthorized: false
}

console.log('connecting mqtt client')
const client = mqtt.connect(host, options)

client.on('error', (err) => {
  console.log(err)
  client.end()
})

client.on('connect', () => {
  console.log('client connected:' + clientId)
  client.subscribe('topic', { qos: 0 })
  client.publish('topic', 'wss secure connection demo...!', { qos: 0, retain: false })
})

client.on('message', (topic, message, packet) => {
  console.log('Received Message:= ' + message.toString() + '\nOn topic:= ' + topic)
})

client.on('close', () => {
  console.log(clientId + ' disconnected')
})


================================================
FILE: examples/wss/client_with_proxy.js
================================================
'use strict'

const mqtt = require('mqtt')
const url = require('url')
const HttpsProxyAgent = require('https-proxy-agent')
/*
host: host of the endpoint you want to connect e.g. my.mqqt.host.com
path: path to you endpoint e.g. '/foo/bar/mqtt'
*/
const endpoint = 'wss://<host><path>'
/* create proxy agent
proxy: your proxy e.g. proxy.foo.bar.com
port: http proxy port e.g. 8080
*/
const proxy = process.env.http_proxy || 'http://<proxy>:<port>'
// eslint-disable-next-line
const parsed = url.parse(endpoint)
// eslint-disable-next-line
const proxyOpts = url.parse(proxy)
// true for wss
proxyOpts.secureEndpoint = parsed.protocol ? parsed.protocol === 'wss:' : true
const agent = new HttpsProxyAgent(proxyOpts)
const wsOptions = {
  agent
  // other wsOptions
  // foo:'bar'
}
const mqttOptions = {
  keepalive: 60,
  reschedulePings: true,
  protocolId: 'MQTT',
  protocolVersion: 4,
  reconnectPeriod: 1000,
  connectTimeout: 30 * 1000,
  clean: true,
  clientId: 'testClient',
  wsOptions
}

const client = mqtt.connect(parsed, mqttOptions)

client.on('connect', () => {
  console.log('connected')
})

client.on('error', (a) => {
  console.log('error!' + a)
})

client.on('offline', (a) => {
  console.log('lost connection!' + a)
})

client.on('close', (a) => {
  console.log('connection closed!' + a)
})

client.on('message', (topic, message) => {
  console.log(message.toString())
})


================================================
FILE: help/help.txt
================================================
MQTT.js command line interface, available commands are:

  * publish     publish a message to the broker
  * subscribe   subscribe for updates from the broker
  * version     the current MQTT.js version
  * help        help about commands

Launch 'mqtt help [command]' to know more about the commands.


================================================
FILE: help/publish.txt
================================================
Usage: mqtt publish [opts] topic [message]

Available options:

  -h/--hostname HOST    the broker host
  -p/--port PORT        the broker port
  -i/--client-id ID     the client id
  -q/--qos 0/1/2        the QoS of the message
  -t/--topic TOPIC      the message topic
  -m/--message MSG      the message body
  -r/--retain           send a retained message
  -s/--stdin            read the message body from stdin
  -M/--multiline        read lines from stdin as multiple messages 
  -u/--username USER    the username
  -P/--password PASS    the password
  -C/--protocol PROTO   the protocol to use, 'mqtt',
                        'mqtts', 'ws' or 'wss'
  --key PATH            path to the key file
  --cert PATH           path to the cert file
  --ca PATH             path to the ca certificate
  --insecure            do not verify the server certificate
  --will-topic TOPIC    the will topic
  --will-payload BODY   the will message
  --will-qos 0/1/2      the will qos
  --will-retain         send a will retained message 
  -H/--help             show this


================================================
FILE: help/subscribe.txt
================================================
Usage: mqtt subscribe [opts] [topic]

Available options:

  -h/--hostname HOST    the broker host
  -p/--port PORT        the broker port
  -i/--clientId ID      the client id
  -q/--qos 0/1/2        the QoS of the message
  --no-clean            do not discard any pending message for
                        the given id
  -t/--topic TOPIC      the message topic
  -k/--keepalive SEC    send a ping every SEC seconds
  -u/--username USER    the username
  -P/--password PASS    the password
  -l/--protocol PROTO   the protocol to use, 'mqtt',
                        'mqtts', 'ws' or 'wss'
  --key PATH            path to the key file
  --cert PATH           path to the cert file
  --ca PATH             path to the ca certificate
  --insecure            do not verify the server certificate
  --will-topic TOPIC    the will topic
  --will-message BODY   the will message
  --will-qos 0/1/2      the will qos
  --will-retain         send a will retained message
  -v/--verbose          print the topic before the message
  -H/--help             show this


================================================
FILE: nyc.config.js
================================================

module.exports = {
    include: [
        'src/**',
    ],
    exclude: [
        'src/bin/*',
        'src/lib/BufferedDuplex.ts',
        'src/connect/wx.ts',
        'src/connect/ali.ts',
    ],
    reporter: [
        'text',
        'lcov'
    ],
    branches: 80,
    functions: 89,
    lines: 86,
    statements: 86,
    'check-coverage': true
}

================================================
FILE: package.json
================================================
{
  "name": "mqtt",
  "description": "A library for the MQTT protocol",
  "version": "5.15.0",
  "contributors": [
    "Adam Rudd <adamvrr@gmail.com>",
    "Matteo Collina <matteo.collina@gmail.com> (https://github.com/mcollina)",
    "Siarhei Buntsevich <scarry0506@gmail.com> (https://github.com/scarry1992)",
    "Yoseph Maguire <yomaguir@microsoft.com> (https://github.com/YoDaMa)",
    "Daniel Lando <daniel.sorridi@gmail.com> (https://github.com/robertsLando)"
  ],
  "keywords": [
    "mqtt",
    "publish/subscribe",
    "publish",
    "subscribe"
  ],
  "license": "MIT",
  "repository": {
    "type": "git",
    "url": "git://github.com/mqttjs/MQTT.js.git"
  },
  "main": "./build/index.js",
  "module": "./dist/mqtt.esm.js",
  "bin": {
    "mqtt_pub": "./build/bin/pub.js",
    "mqtt_sub": "./build/bin/sub.js",
    "mqtt": "./build/bin/mqtt.js"
  },
  "files": [
    "dist/",
    "CONTRIBUTING.md",
    "LICENSE.md",
    "help/",
    "build/"
  ],
  "exports": {
    ".": {
      "react-native": "./dist/mqtt.esm.js",
      "browser": {
        "import": "./dist/mqtt.esm.js",
        "default": "./dist/mqtt.min.js"
      },
      "default": "./build/index.js"
    },
    "./package.json": "./package.json",
    "./*.map": "./build/*.js.map",
    "./dist/*": "./dist/*.js",
    "./*": "./build/*.js"
  },
  "types": "build/index.d.ts",
  "typesVersions": {
    "*": {
      "*": [
        "./build/index.d.ts"
      ]
    }
  },
  "scripts": {
    "lint": "eslint --ext .ts .",
    "lint-fix": "eslint --fix --ext .ts .",
    "build:ts": "rimraf build/ && tsc -p tsconfig.build.json",
    "build:browser": "node esbuild.js",
    "build": "npm run build:ts && npm run build:browser",
    "prepare": "npm run build",
    "unit-test:node": "node -r esbuild-register --test-concurrency 4 --test-reporter=junit --test-reporter-destination=junit.xml --test-reporter=spec --test-reporter-destination=stdout --test test/node/*.ts ",
    "unit-test:browser": "wtr",
    "test:node": "node_modules/.bin/nyc npm run unit-test:node",
    "test:browser": "npm run build && npm run unit-test:browser",
    "test": "npm run test:node",
    "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s && git add CHANGELOG.md",
    "changelog-init": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0",
    "release": "read -p 'GITHUB_TOKEN: ' GITHUB_TOKEN && export GITHUB_TOKEN=$GITHUB_TOKEN && release-it"
  },
  "publishConfig": {
    "registry": "https://registry.npmjs.org",
    "provenance": true
  },
  "pre-commit": [
    "lint"
  ],
  "engines": {
    "node": ">=16.0.0"
  },
  "browser": {
    "./mqtt.js": "./dist/mqtt.js",
    "fs": false,
    "tls": false,
    "net": false
  },
  "dependencies": {
    "@types/readable-stream": "^4.0.21",
    "@types/ws": "^8.18.1",
    "commist": "^3.2.0",
    "concat-stream": "^2.0.0",
    "debug": "^4.4.1",
    "help-me": "^5.0.0",
    "lru-cache": "^10.4.3",
    "minimist": "^1.2.8",
    "mqtt-packet": "^9.0.2",
    "number-allocator": "^1.0.14",
    "readable-stream": "^4.7.0",
    "rfdc": "^1.4.1",
    "socks": "^2.8.6",
    "split2": "^4.2.0",
    "worker-timers": "^8.0.23",
    "ws": "^8.18.3"
  },
  "devDependencies": {
    "@eslint/eslintrc": "^3.3.1",
    "@eslint/js": "^9.32.0",
    "@esm-bundle/chai": "^4.3.4",
    "@release-it/conventional-changelog": "^10.0.1",
    "@tsconfig/node20": "^20.1.6",
    "@types/chai": "^5.2.2",
    "@types/node": "^20.17.16",
    "@types/sinon": "^17.0.4",
    "@types/tape": "^5.8.1",
    "@typescript-eslint/eslint-plugin": "^8.38.0",
    "@typescript-eslint/parser": "^8.38.0",
    "@web/test-runner": "^0.20.2",
    "@web/test-runner-playwright": "^0.11.1",
    "aedes-cli": "^0.8.0",
    "chai": "^5.2.1",
    "chokidar": "^4.0.3",
    "conventional-changelog-cli": "^5.0.0",
    "end-of-stream": "^1.4.5",
    "esbuild": "^0.25.8",
    "esbuild-plugin-polyfill-node": "^0.3.0",
    "esbuild-register": "^3.6.0",
    "eslint": "^9.32.0",
    "eslint-config-prettier": "^10.1.8",
    "eslint-plugin-import": "^2.32.0",
    "eslint-plugin-prettier": "^5.5.3",
    "global": "^4.4.0",
    "globals": "^16.3.0",
    "leaked-handles": "^5.2.0",
    "mkdirp": "^3.0.1",
    "mqtt-connection": "^4.1.0",
    "mqtt-level-store": "^3.1.0",
    "nyc": "^17.1.0",
    "pre-commit": "^1.2.2",
    "prettier": "^3.6.2",
    "release-it": "^19.0.4",
    "rimraf": "^6.0.1",
    "should": "^13.2.3",
    "sinon": "^17.0.2",
    "snazzy": "^9.0.0",
    "tape": "^5.9.0",
    "ts-node": "^10.9.2",
    "typescript": "^5.8.3"
  }
}


================================================
FILE: src/bin/mqtt.ts
================================================
#!/usr/bin/env node

/*
 * Copyright (c) 2015-2015 MQTT.js contributors.
 * Copyright (c) 2011-2014 Adam Rudd.
 *
 * See LICENSE for more information
 */
import path from 'path'
import Commist from 'commist'
import help from 'help-me'
import publish from './pub'
import subscribe from './sub'
import { MQTTJS_VERSION } from '../mqtt'

const helpMe = help({
	dir: path.join(__dirname, '../../', 'help'),
	ext: '.txt',
})

const commist = Commist()

commist.register('publish', publish)
commist.register('pub', publish)

commist.register('subscribe', subscribe)
commist.register('sub', subscribe)

commist.register('version', () => {
	console.log('MQTT.js version:', MQTTJS_VERSION)
})
commist.register('help', helpMe.toStdout)

if (commist.parse(process.argv.slice(2)) !== null) {
	console.log('No such command:', process.argv[2], '\n')
	helpMe.toStdout()
}


================================================
FILE: src/bin/pub.ts
================================================
#!/usr/bin/env node

import { Writable } from 'readable-stream'
import path from 'path'
import fs from 'fs'
import concat from 'concat-stream'
import help from 'help-me'

import minimist, { type ParsedArgs } from 'minimist'
import split2 from 'split2'
import { type IClientOptions, type IClientPublishOptions } from 'src/lib/client'
import { pipeline } from 'stream'
import { connect } from '../mqtt'

const helpMe = help({
	dir: path.join(__dirname, '../../', 'help'),
})

function send(args: ParsedArgs) {
	const client = connect(args as IClientOptions)
	client.on('connect', () => {
		client.publish(
			args.topic,
			args.message,
			args as IClientPublishOptions,
			(err) => {
				if (err) {
					console.warn(err)
				}
				client.end()
			},
		)
	})
	client.on('error', (err) => {
		console.warn(err)
		client.end()
	})
}

function multisend(args: ParsedArgs) {
	const client = connect(args as IClientOptions)
	const sender = new Writable({
		objectMode: true,
	})
	sender._write = (line, enc, cb) => {
		client.publish(
			args.topic,
			line.trim(),
			args as IClientPublishOptions,
			cb,
		)
	}

	client.on('connect', () => {
		pipeline(process.stdin, split2(), sender, (err) => {
			client.end()
			if (err) {
				throw err
			}
		})
	})
}

export default function start(args: string[]) {
	const parsedArgs = minimist(args, {
		string: [
			'hostname',
			'username',
			'password',
			'key',
			'cert',
			'ca',
			'message',
			'clientId',
			'i',
			'id',
		],
		boolean: ['stdin', 'retain', 'help', 'insecure', 'multiline'],
		alias: {
			port: 'p',
			hostname: ['h', 'host'],
			topic: 't',
			message: 'm',
			qos: 'q',
			clientId: ['i', 'id'],
			retain: 'r',
			username: 'u',
			password: 'P',
			stdin: 's',
			multiline: 'M',
			protocol: ['C', 'l'],
			help: 'H',
			ca: 'cafile',
		},
		default: {
			host: 'localhost',
			qos: 0,
			retain: false,
			topic: '',
			message: '',
		},
	})

	if (parsedArgs.help) {
		return helpMe.toStdout('publish')
	}

	if (parsedArgs.key) {
		parsedArgs.key = fs.readFileSync(parsedArgs.key)
	}

	if (parsedArgs.cert) {
		parsedArgs.cert = fs.readFileSync(parsedArgs.cert)
	}

	if (parsedArgs.ca) {
		parsedArgs.ca = fs.readFileSync(parsedArgs.ca)
	}

	if (parsedArgs.key && parsedArgs.cert && !parsedArgs.protocol) {
		parsedArgs.protocol = 'mqtts'
	}

	if (parsedArgs.port) {
		if (typeof parsedArgs.port !== 'number') {
			console.warn(
				"# Port: number expected, '%s' was given.",
				typeof parsedArgs.port,
			)
			return
		}
	}

	if (parsedArgs['will-topic']) {
		parsedArgs.will = {}
		parsedArgs.will.topic = parsedArgs['will-topic']
		parsedArgs.will.payload = parsedArgs['will-message']
		parsedArgs.will.qos = parsedArgs['will-qos']
		parsedArgs.will.retain = parsedArgs['will-retain']
	}

	if (parsedArgs.insecure) {
		parsedArgs.rejectUnauthorized = false
	}

	parsedArgs.topic = (parsedArgs.topic || parsedArgs._.shift())?.toString()
	parsedArgs.message = (
		parsedArgs.message || parsedArgs._.shift()
	)?.toString()

	if (!parsedArgs.topic) {
		console.error('missing topic\n')
		return helpMe.toStdout('publish')
	}

	if (parsedArgs.stdin) {
		if (parsedArgs.multiline) {
			multisend(parsedArgs)
		} else {
			process.stdin.pipe(
				concat((data) => {
					parsedArgs.message = data
					send(parsedArgs)
				}),
			)
		}
	} else {
		send(parsedArgs)
	}
}

if (require.main === module) {
	start(process.argv.slice(2))
}


================================================
FILE: src/bin/sub.ts
================================================
#!/usr/bin/env node

import path from 'path'
import fs from 'fs'
import minimist from 'minimist'
import help from 'help-me'
import { type IClientOptions } from 'src/lib/client'
import { connect } from '../mqtt'

const helpMe = help({
	dir: path.join(__dirname, '../../', 'help'),
})

export default function start(args: string[]) {
	const parsedArgs = minimist(args, {
		string: [
			'hostname',
			'username',
			'password',
			'key',
			'cert',
			'ca',
			'clientId',
			'i',
			'id',
		],
		boolean: ['stdin', 'help', 'clean', 'insecure'],
		alias: {
			port: 'p',
			hostname: ['h', 'host'],
			topic: 't',
			qos: 'q',
			clean: 'c',
			keepalive: 'k',
			clientId: ['i', 'id'],
			username: 'u',
			password: 'P',
			protocol: ['C', 'l'],
			verbose: 'v',
			help: '-H',
			ca: 'cafile',
		},
		default: {
			host: 'localhost',
			qos: 0,
			retain: false,
			clean: true,
			keepAlive: 30, // 30 sec
		},
	})

	if (parsedArgs.help) {
		return helpMe.toStdout('subscribe')
	}

	parsedArgs.topic = parsedArgs.topic || parsedArgs._.shift()

	if (!parsedArgs.topic) {
		console.error('missing topic\n')
		return helpMe.toStdout('subscribe')
	}

	if (parsedArgs.key) {
		parsedArgs.key = fs.readFileSync(parsedArgs.key)
	}

	if (parsedArgs.cert) {
		parsedArgs.cert = fs.readFileSync(parsedArgs.cert)
	}

	if (parsedArgs.ca) {
		parsedArgs.ca = fs.readFileSync(parsedArgs.ca)
	}

	if (parsedArgs.key && parsedArgs.cert && !parsedArgs.protocol) {
		parsedArgs.protocol = 'mqtts'
	}

	if (parsedArgs.insecure) {
		parsedArgs.rejectUnauthorized = false
	}

	if (parsedArgs.port) {
		if (typeof parsedArgs.port !== 'number') {
			console.warn(
				"# Port: number expected, '%s' was given.",
				typeof parsedArgs.port,
			)
			return
		}
	}

	if (parsedArgs['will-topic']) {
		parsedArgs.will = {}
		parsedArgs.will.topic = parsedArgs['will-topic']
		parsedArgs.will.payload = parsedArgs['will-message']
		parsedArgs.will.qos = parsedArgs['will-qos']
		parsedArgs.will.retain = parsedArgs['will-retain']
	}

	parsedArgs.keepAlive = parsedArgs['keep-alive']

	const client = connect(parsedArgs as IClientOptions)

	client.on('connect', () => {
		client.subscribe(
			parsedArgs.topic,
			{ qos: parsedArgs.qos },
			(err, result) => {
				if (err) {
					console.error(err)
					process.exit(1)
				}

				result.forEach((sub) => {
					if (sub.qos > 2) {
						console.error(
							'subscription negated to',
							sub.topic,
							'with code',
							sub.qos,
						)
						process.exit(1)
					}
				})
			},
		)
	})

	client.on('message', (topic, payload) => {
		if (parsedArgs.verbose) {
			console.log(topic, payload.toString())
		} else {
			console.log(payload.toString())
		}
	})

	client.on('error', (err) => {
		console.warn(err)
		client.end()
	})
}

if (require.main === module) {
	start(process.argv.slice(2))
}


================================================
FILE: src/index.ts
================================================
import * as mqtt from './mqtt'

export default mqtt
export * from './mqtt'


================================================
FILE: src/lib/BufferedDuplex.ts
================================================
import { Duplex, type Transform } from 'readable-stream'
import { Buffer } from 'buffer'
import { type IClientOptions } from './client'

/**
 * Utils writev function for browser, ensure to write Buffers to socket (convert strings).
 */
export function writev(
	chunks: { chunk: any; encoding: string }[],
	cb: (err?: Error) => void,
) {
	const buffers = new Array(chunks.length)
	for (let i = 0; i < chunks.length; i++) {
		if (typeof chunks[i].chunk === 'string') {
			buffers[i] = Buffer.from(chunks[i].chunk, 'utf8')
		} else {
			buffers[i] = chunks[i].chunk
		}
	}

	this._write(Buffer.concat(buffers), 'binary', cb)
}

/**
 * How this works:
 * - `socket` is the `WebSocket` instance, the connection to our broker.
 * - `proxy` is a `Transform`, it ensure data written to the `socket` is a `Buffer`.
 * This class buffers the data written to the `proxy` (so then to `socket`) until the `socket` is ready.
 * The stream returned from this class, will be passed to the `MqttClient`.
 */
export class BufferedDuplex extends Duplex {
	public socket: WebSocket

	private proxy: Transform

	private isSocketOpen: boolean

	private writeQueue: Array<{
		chunk: any
		encoding: string
		cb: (err?: Error) => void
	}>

	constructor(opts: IClientOptions, proxy: Transform, socket: WebSocket) {
		super({
			objectMode: true,
		})
		this.proxy = proxy
		this.socket = socket
		this.writeQueue = []

		if (!opts.objectMode) {
			this._writev = writev.bind(this)
		}

		this.isSocketOpen = false

		this.proxy.on('data', (chunk) => {
			if (!this.destroyed && this.readable) {
				this.push(chunk)
			}
		})
	}

	_read(size?: number): void {
		this.proxy.read(size)
	}

	_write(chunk: any, encoding: string, cb: (err?: Error) => void) {
		if (!this.isSocketOpen) {
			// Buffer the data in a queue
			this.writeQueue.push({ chunk, encoding, cb })
		} else {
			this.writeToProxy(chunk, encoding, cb)
		}
	}

	_final(callback: (error?: Error) => void): void {
		this.writeQueue = []
		this.proxy.end(callback)
	}

	_destroy(err: Error, callback: (error: Error) => void): void {
		this.writeQueue = []
		// do not pass error here otherwise we should listen for `error` event on proxy to prevent uncaught exception
		this.proxy.destroy()
		callback(err)
	}

	/** Method to call when socket is ready to stop buffering writes */
	socketReady() {
		this.emit('connect')
		this.isSocketOpen = true
		this.processWriteQueue()
	}

	private writeToProxy(
		chunk: any,
		encoding: string,
		cb: (err?: Error) => void,
	) {
		if (this.proxy.write(chunk, encoding) === false) {
			this.proxy.once('drain', cb)
		} else {
			cb()
		}
	}

	private processWriteQueue() {
		while (this.writeQueue.length > 0) {
			const { chunk, encoding, cb } = this.writeQueue.shift()!
			this.writeToProxy(chunk, encoding, cb)
		}
	}
}


================================================
FILE: src/lib/KeepaliveManager.ts
================================================
import type MqttClient from './client'
import getTimer, { type Timer } from './get-timer'
import type { TimerVariant } from './shared'

export default class KeepaliveManager {
	private _keepalive: number

	private timerId: number

	private timer: Timer

	private destroyed = false

	private counter: number

	private client: MqttClient

	private _keepaliveTimeoutTimestamp: number

	private _intervalEvery: number

	/** Timestamp of next keepalive timeout */
	get keepaliveTimeoutTimestamp() {
		return this._keepaliveTimeoutTimestamp
	}

	/** Milliseconds of the actual interval */
	get intervalEvery() {
		return this._intervalEvery
	}

	get keepalive() {
		return this._keepalive
	}

	constructor(client: MqttClient, variant: TimerVariant | Timer) {
		this.client = client
		this.timer =
			typeof variant === 'object' &&
			'set' in variant &&
			'clear' in variant
				? variant
				: getTimer(variant)
		this.setKeepalive(client.options.keepalive)
	}

	private clear() {
		if (this.timerId) {
			this.timer.clear(this.timerId)
			this.timerId = null
		}
	}

	/** Change the keepalive */
	setKeepalive(value: number) {
		// keepalive is in seconds
		value *= 1000

		if (isNaN(value) || value <= 0 || value > 2147483647) {
			throw new Error(
				`Keepalive value must be an integer between 0 and 2147483647. Provided value is ${value}`,
			)
		}

		this._keepalive = value

		this.reschedule()

		this.client['log'](`KeepaliveManager: set keepalive to ${value}ms`)
	}

	destroy() {
		this.clear()
		this.destroyed = true
	}

	reschedule() {
		if (this.destroyed) {
			return
		}

		this.clear()
		this.counter = 0

		// https://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Figure_3.5_Keep
		const keepAliveTimeout = Math.ceil(this._keepalive * 1.5)

		this._keepaliveTimeoutTimestamp = Date.now() + keepAliveTimeout
		this._intervalEvery = Math.ceil(this._keepalive / 2)

		this.timerId = this.timer.set(() => {
			// this should never happen, but just in case
			if (this.destroyed) {
				return
			}

			this.counter += 1

			// after keepalive seconds, send a pingreq
			if (this.counter === 2) {
				this.client.sendPing()
			} else if (this.counter > 2) {
				this.client.onKeepaliveTimeout()
			}
		}, this._intervalEvery)
	}
}


================================================
FILE: src/lib/TypedEmitter.ts
================================================
import EventEmitter from 'events'
import { applyMixin } from './shared'

export type EventHandler =
	// Add more overloads as necessary
	| ((arg1: any, arg2: any, arg3: any, arg4: any) => void)
	| ((arg1: any, arg2: any, arg3: any) => void)
	| ((arg1: any, arg2: any) => void)
	| ((arg1: any) => void)
	| ((...args: any[]) => void)

export interface TypedEventEmitter<
	TEvents extends Record<keyof TEvents, EventHandler>,
> {
	on<TEvent extends keyof TEvents>(
		event: TEvent,
		callback: TEvents[TEvent],
	): this
	once<TEvent extends keyof TEvents>(
		event: TEvent,
		callback: TEvents[TEvent],
	): this
	prependListener<TEvent extends keyof TEvents>(
		event: TEvent,
		callback: TEvents[TEvent],
	): this
	prependOnceListener<TEvent extends keyof TEvents>(
		event: TEvent,
		callback: TEvents[TEvent],
	): this

	removeListener<TEvent extends keyof TEvents>(
		event: TEvent,
		callback: TEvents[TEvent],
	): this
	off<TEvent extends keyof TEvents>(
		event: TEvent,
		callback: TEvents[TEvent],
	): this

	removeAllListeners(event?: keyof TEvents): this

	emit<TEvent extends keyof TEvents>(
		event: TEvent,
		...args: Parameters<TEvents[TEvent]>
	): boolean

	setMaxListeners(n: number): this
	getMaxListeners(): number

	listeners<TEvent extends keyof TEvents>(
		eventName: TEvent,
	): TEvents[TEvent][]
	rawListeners<TEvent extends keyof TEvents>(
		eventName: TEvent,
	): TEvents[TEvent][]
	listenerCount<TEvent extends keyof TEvents>(
		event: TEvent,
		listener?: TEvents[TEvent],
	): number

	eventNames(): Array<keyof TEvents>
}

// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
export class TypedEventEmitter<
	TEvents extends Record<keyof TEvents, EventHandler>,
> {}

// Make TypedEventEmitter inherit from EventEmitter without actually extending
applyMixin(TypedEventEmitter, EventEmitter)


================================================
FILE: src/lib/client.ts
================================================
/**
 * Module dependencies
 */
import mqttPacket, {
	type IAuthPacket,
	IConnackPacket,
	IDisconnectPacket,
	IPublishPacket,
	type ISubscribePacket,
	type ISubscription,
	type IUnsubscribePacket,
	Packet,
	type QoS,
	type ISubackPacket,
	type IConnectPacket,
} from 'mqtt-packet'
import { type DuplexOptions, Writable } from 'readable-stream'
import clone from 'rfdc/default'
import _debug from 'debug'
import type { ClientOptions } from 'ws'
import { type ClientRequestArgs } from 'http'
import * as validations from './validations'
import Store, { type IStore } from './store'
import handlePacket from './handlers'
import DefaultMessageIdProvider, {
	type IMessageIdProvider,
} from './default-message-id-provider'
import TopicAliasRecv from './topic-alias-recv'
import {
	type DoneCallback,
	type ErrorWithReasonCode,
	ErrorWithSubackPacket,
	type GenericCallback,
	type IStream,
	MQTTJS_VERS
Download .txt
gitextract__ue8z3qn/

├── .editorconfig
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.yml
│   │   ├── config.yml
│   │   └── feature_request.md
│   └── workflows/
│       ├── ISSUE_TEMPLATE/
│       │   ├── bug_report.yml
│       │   ├── config.yml
│       │   └── feature_request.md
│       ├── browser-tests.yml
│       ├── electron-tests.yml
│       ├── mqttjs-test.yml
│       ├── release-it.yml
│       ├── semantic-pr.yml
│       └── stale.yml
├── .gitignore
├── .prettierignore
├── .prettierrc.js
├── .release-it.json
├── CHANGELOG.OLD.md
├── CHANGELOG.md
├── CONTRIBUTING.md
├── DEVELOPMENT.md
├── LICENSE.md
├── README.md
├── benchmarks/
│   ├── bombing.js
│   └── throughputCounter.js
├── electron-test/
│   ├── .gitignore
│   ├── README
│   ├── forge.config.js
│   ├── package.json
│   ├── src/
│   │   ├── index.css
│   │   ├── index.html
│   │   ├── index.js
│   │   └── renderer.js
│   ├── test/
│   │   ├── service/
│   │   │   └── server_launcher.ts
│   │   └── specs/
│   │       └── test.e2e.ts
│   ├── tsconfig.json
│   └── wdio.conf.ts
├── esbuild.js
├── eslint.config.js
├── example.ts
├── examples/
│   ├── client/
│   │   ├── secure-client.js
│   │   ├── simple-both.js
│   │   ├── simple-publish.js
│   │   └── simple-subscribe.js
│   ├── tls client/
│   │   ├── crt.ca.cg.pem
│   │   ├── mqttclient.js
│   │   ├── tls-cert.pem
│   │   └── tls-key.pem
│   ├── vite-example/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── index.html
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── App.vue
│   │   │   ├── assets/
│   │   │   │   ├── base.css
│   │   │   │   └── main.css
│   │   │   └── main.js
│   │   └── vite.config.js
│   ├── ws/
│   │   ├── aedes_server.js
│   │   └── client.js
│   └── wss/
│       └── client_with_proxy.js
├── help/
│   ├── help.txt
│   ├── publish.txt
│   └── subscribe.txt
├── nyc.config.js
├── package.json
├── src/
│   ├── bin/
│   │   ├── mqtt.ts
│   │   ├── pub.ts
│   │   └── sub.ts
│   ├── index.ts
│   ├── lib/
│   │   ├── BufferedDuplex.ts
│   │   ├── KeepaliveManager.ts
│   │   ├── TypedEmitter.ts
│   │   ├── client.ts
│   │   ├── connect/
│   │   │   ├── ali.ts
│   │   │   ├── index.ts
│   │   │   ├── socks.ts
│   │   │   ├── tcp.ts
│   │   │   ├── tls.ts
│   │   │   ├── ws.ts
│   │   │   └── wx.ts
│   │   ├── default-message-id-provider.ts
│   │   ├── get-timer.ts
│   │   ├── handlers/
│   │   │   ├── ack.ts
│   │   │   ├── auth.ts
│   │   │   ├── connack.ts
│   │   │   ├── index.ts
│   │   │   ├── publish.ts
│   │   │   └── pubrel.ts
│   │   ├── is-browser.ts
│   │   ├── shared.ts
│   │   ├── store.ts
│   │   ├── topic-alias-recv.ts
│   │   ├── topic-alias-send.ts
│   │   ├── unique-message-id-provider.ts
│   │   └── validations.ts
│   └── mqtt.ts
├── test/
│   ├── browser/
│   │   ├── certs/
│   │   │   ├── server-cert.pem
│   │   │   └── server-key.pem
│   │   ├── test.js
│   │   └── worker.js
│   └── node/
│       ├── abstract_client.ts
│       ├── abstract_store.ts
│       ├── client.ts
│       ├── client_mqtt5.ts
│       ├── helpers/
│       │   ├── TeardownHelper.ts
│       │   ├── leaked.ts
│       │   ├── port_list.ts
│       │   ├── private-csr.pem
│       │   ├── private-key.pem
│       │   ├── public-cert.pem
│       │   ├── public-key.pem
│       │   ├── server.ts
│       │   ├── server_process.ts
│       │   ├── tls-cert.pem
│       │   ├── tls-key.pem
│       │   ├── wrong-cert.pem
│       │   ├── wrong-csr.pem
│       │   └── wrong-key.pem
│       ├── keepaliveManager.ts
│       ├── message-id-provider.ts
│       ├── mqtt.ts
│       ├── mqtt_store.ts
│       ├── secure_client.ts
│       ├── server.ts
│       ├── server_helpers_for_client_tests.ts
│       ├── socks.ts
│       ├── store.ts
│       ├── unique_message_id_provider_client.ts
│       ├── util.ts
│       └── websocket_client.ts
├── tsconfig.build.json
├── tsconfig.json
└── web-test-runner.config.mjs
Download .txt
SYMBOL INDEX (268 symbols across 43 files)

FILE: benchmarks/bombing.js
  function count (line 15) | function count() {
  function publish (line 22) | function publish() {

FILE: benchmarks/throughputCounter.js
  function count (line 15) | function count() {

FILE: electron-test/test/service/server_launcher.ts
  class ServerLauncher (line 6) | class ServerLauncher implements Services.ServiceInstance {
    method constructor (line 10) | constructor() {
    method onPrepare (line 14) | async onPrepare(): Promise<void> {
    method onComplete (line 29) | async onComplete(): Promise<void> {

FILE: esbuild.js
  method setup (line 28) | setup(build) {
  method setup (line 49) | setup(build) {
  function run (line 70) | async function run() {

FILE: example.ts
  function publish (line 14) | function publish() {

FILE: examples/client/secure-client.js
  constant KEY (line 6) | const KEY = fs.readFileSync(path.join(__dirname, '..', '..', 'test', 'he...
  constant CERT (line 7) | const CERT = fs.readFileSync(path.join(__dirname, '..', '..', 'test', 'h...
  constant PORT (line 9) | const PORT = 8443

FILE: examples/tls client/mqttclient.js
  constant KEY (line 20) | const KEY = fs.readFileSync(path.join(__dirname, '/tls-key.pem'))
  constant CERT (line 21) | const CERT = fs.readFileSync(path.join(__dirname, '/tls-cert.pem'))
  constant TRUSTED_CA_LIST (line 22) | const TRUSTED_CA_LIST = fs.readFileSync(path.join(__dirname, '/crt.ca.cg...
  constant PORT (line 24) | const PORT = 1883
  constant HOST (line 25) | const HOST = 'stark'

FILE: src/bin/pub.ts
  function send (line 19) | function send(args: ParsedArgs) {
  function multisend (line 40) | function multisend(args: ParsedArgs) {
  function start (line 64) | function start(args: string[]) {

FILE: src/bin/sub.ts
  function start (line 14) | function start(args: string[]) {

FILE: src/lib/BufferedDuplex.ts
  function writev (line 8) | function writev(
  class BufferedDuplex (line 31) | class BufferedDuplex extends Duplex {
    method constructor (line 44) | constructor(opts: IClientOptions, proxy: Transform, socket: WebSocket) {
    method _read (line 65) | _read(size?: number): void {
    method _write (line 69) | _write(chunk: any, encoding: string, cb: (err?: Error) => void) {
    method _final (line 78) | _final(callback: (error?: Error) => void): void {
    method _destroy (line 83) | _destroy(err: Error, callback: (error: Error) => void): void {
    method socketReady (line 91) | socketReady() {
    method writeToProxy (line 97) | private writeToProxy(
    method processWriteQueue (line 109) | private processWriteQueue() {

FILE: src/lib/KeepaliveManager.ts
  class KeepaliveManager (line 5) | class KeepaliveManager {
    method keepaliveTimeoutTimestamp (line 23) | get keepaliveTimeoutTimestamp() {
    method intervalEvery (line 28) | get intervalEvery() {
    method keepalive (line 32) | get keepalive() {
    method constructor (line 36) | constructor(client: MqttClient, variant: TimerVariant | Timer) {
    method clear (line 47) | private clear() {
    method setKeepalive (line 55) | setKeepalive(value: number) {
    method destroy (line 72) | destroy() {
    method reschedule (line 77) | reschedule() {

FILE: src/lib/TypedEmitter.ts
  type EventHandler (line 4) | type EventHandler =
  type TypedEventEmitter (line 12) | interface TypedEventEmitter<
  class TypedEventEmitter (line 66) | class TypedEventEmitter<

FILE: src/lib/client.ts
  type BaseMqttProtocol (line 70) | type BaseMqttProtocol =
  type MqttProtocolWithUnix (line 83) | type MqttProtocolWithUnix = `${BaseMqttProtocol}+unix`
  type MqttProtocol (line 85) | type MqttProtocol = BaseMqttProtocol | MqttProtocolWithUnix
  type StorePutCallback (line 87) | type StorePutCallback = () => void
  type ISecureClientOptions (line 89) | interface ISecureClientOptions {
  type AckHandler (line 113) | type AckHandler = (
  type IClientOptions (line 120) | interface IClientOptions extends ISecureClientOptions {
  type IClientPublishOptions (line 311) | interface IClientPublishOptions {
  type IClientReconnectOptions (line 334) | interface IClientReconnectOptions {
  type IClientSubscribeProperties (line 344) | interface IClientSubscribeProperties {
  type IClientSubscribeOptions (line 351) | interface IClientSubscribeOptions extends IClientSubscribeProperties {
  type ISubscriptionRequest (line 369) | interface ISubscriptionRequest extends IClientSubscribeOptions {
  type ISubscriptionGrant (line 376) | interface ISubscriptionGrant
  type ISubscriptionMap (line 384) | type ISubscriptionMap = {
  type IClientUnsubscribeProperties (line 393) | interface IClientUnsubscribeProperties {
  type OnConnectCallback (line 401) | type OnConnectCallback = (packet: IConnackPacket) => void
  type OnDisconnectCallback (line 402) | type OnDisconnectCallback = (packet: IDisconnectPacket) => void
  type ClientSubscribeCallback (line 403) | type ClientSubscribeCallback = (
  type OnMessageCallback (line 408) | type OnMessageCallback = (
  type OnPacketCallback (line 413) | type OnPacketCallback = (packet: Packet) => void
  type OnCloseCallback (line 414) | type OnCloseCallback = () => void
  type OnErrorCallback (line 415) | type OnErrorCallback = (error: Error | ErrorWithReasonCode) => void
  type PacketCallback (line 416) | type PacketCallback = (
  type CloseCallback (line 420) | type CloseCallback = (error?: Error) => void
  type MqttClientEventCallbacks (line 422) | interface MqttClientEventCallbacks {
  class MqttClient (line 443) | class MqttClient extends TypedEventEmitter<MqttClientEventCallbacks> {
    method defaultId (line 522) | public static defaultId() {
    method constructor (line 526) | constructor(streamBuilder: StreamBuilder, options: IClientOptions) {
    method handleAuth (line 725) | public handleAuth(packet: IAuthPacket, callback: PacketCallback) {
    method handleMessage (line 737) | public handleMessage(packet: IPublishPacket, callback: DoneCallback) {
    method _nextId (line 745) | private _nextId() {
    method getLastMessageId (line 753) | public getLastMessageId() {
    method connect (line 760) | public connect() {
    method publish (line 959) | public publish(
    method publishAsync (line 1057) | public publishAsync(
    method subscribe (line 1105) | public subscribe(
    method subscribeAsync (line 1338) | public subscribeAsync(
    method unsubscribe (line 1379) | public unsubscribe(
    method unsubscribeAsync (line 1465) | public unsubscribeAsync(
    method end (line 1499) | public end(
    method endAsync (line 1605) | public endAsync(
    method removeOutgoingMessage (line 1630) | public removeOutgoingMessage(messageId: number): MqttClient {
    method reconnect (line 1651) | public reconnect(
    method _flushVolatile (line 1688) | private _flushVolatile() {
    method _flush (line 1708) | private _flush() {
    method _removeTopicAliasAndRecoverTopicName (line 1722) | private _removeTopicAliasAndRecoverTopicName(packet: IPublishPacket) {
    method _checkDisconnecting (line 1753) | private _checkDisconnecting(callback?: GenericCallback<any>) {
    method _reconnect (line 1768) | private _reconnect() {
    method _setupReconnect (line 1785) | private _setupReconnect() {
    method _clearReconnect (line 1813) | private _clearReconnect() {
    method _cleanUp (line 1825) | private _cleanUp(forced: boolean, done?: DoneCallback, opts = {}) {
    method _storeAndSend (line 1885) | private _storeAndSend(
    method _applyTopicAlias (line 1917) | private _applyTopicAlias(packet: Packet) {
    method _noop (line 2000) | private _noop(err?: Error) {
    method _writePacket (line 2005) | private _writePacket(packet: Packet, cb?: DoneCallback) {
    method _sendPacket (line 2037) | private _sendPacket(
    method _storePacket (line 2114) | private _storePacket(
    method _setupKeepaliveManager (line 2159) | private _setupKeepaliveManager() {
    method _destroyKeepaliveManager (line 2173) | private _destroyKeepaliveManager() {
    method reschedulePing (line 2184) | public reschedulePing(force = false) {
    method _reschedulePing (line 2197) | private _reschedulePing() {
    method sendPing (line 2202) | public sendPing() {
    method onKeepaliveTimeout (line 2207) | public onKeepaliveTimeout() {
    method _resubscribe (line 2217) | private _resubscribe() {
    method _onConnect (line 2267) | private _onConnect(packet: IConnackPacket) {
    method _invokeStoreProcessingQueue (line 2384) | private _invokeStoreProcessingQueue() {
    method _invokeAllStoreProcessingQueue (line 2397) | private _invokeAllStoreProcessingQueue() {
    method _flushStoreProcessingQueue (line 2403) | private _flushStoreProcessingQueue() {
    method _removeOutgoingAndStoreMessage (line 2417) | private _removeOutgoingAndStoreMessage(

FILE: src/lib/connect/ali.ts
  function buildProxy (line 13) | function buildProxy() {
  function setDefaultOpts (line 37) | function setDefaultOpts(opts: IClientOptions) {
  function buildUrl (line 50) | function buildUrl(opts: IClientOptions, client: MqttClient) {
  function bindEventHandler (line 62) | function bindEventHandler() {

FILE: src/lib/connect/index.ts
  function parseAuthOptions (line 26) | function parseAuthOptions(opts: IClientOptions) {
  function connect (line 46) | function connect(
  function connectAsync (line 240) | function connectAsync(

FILE: src/lib/connect/socks.ts
  type SocksConnectionOptions (line 13) | interface SocksConnectionOptions {
  class ProxyStream (line 18) | class ProxyStream extends Duplex {
    method constructor (line 23) | constructor() {
    method _start (line 29) | _start(socket: Socket): void {
    method _write (line 53) | _write(
    method _read (line 63) | _read(size: number): void {
    method _destroy (line 69) | _destroy(
  function fatal (line 104) | function fatal<T>(e: T): T {
  function typeFromProtocol (line 113) | function typeFromProtocol(
  function parseSocksUrl (line 134) | function parseSocksUrl(url: string): [SocksProxy, boolean] {
  function connectSocks (line 160) | async function connectSocks(
  function openSocks (line 209) | function openSocks(

FILE: src/lib/connect/tls.ts
  function connect (line 10) | function connect(opts: IClientOptions): TLSSocket {
  function handleTLSerrors (line 55) | function handleTLSerrors(err: Error) {

FILE: src/lib/connect/ws.ts
  constant WSS_OPTIONS (line 13) | const WSS_OPTIONS = [
  function buildUrl (line 22) | function buildUrl(opts: IClientOptions, client: MqttClient) {
  function setDefaultOpts (line 30) | function setDefaultOpts(opts: IClientOptions) {
  function setDefaultBrowserOpts (line 63) | function setDefaultBrowserOpts(opts: IClientOptions) {
  function createWebSocket (line 95) | function createWebSocket(
  function createBrowserWebSocket (line 124) | function createBrowserWebSocket(client: MqttClient, opts: IClientOptions) {
  function buildProxy (line 214) | function buildProxy(
  function onOpen (line 229) | function onOpen() {
  function onClose (line 239) | function onClose(event: CloseEvent) {
  function onError (line 248) | function onError(err: Event) {
  function onMessage (line 258) | async function onMessage(event: MessageEvent) {
  function socketWriteBrowser (line 270) | function socketWriteBrowser(
  function socketEndBrowser (line 295) | function socketEndBrowser(done: (error?: Error, data?: any) => void) {

FILE: src/lib/connect/wx.ts
  function buildProxy (line 17) | function buildProxy() {
  function setDefaultOpts (line 41) | function setDefaultOpts(opts) {
  function buildUrl (line 54) | function buildUrl(opts: IClientOptions, client: MqttClient) {
  function bindEventHandler (line 66) | function bindEventHandler() {
  method success (line 116) | success() {
  method fail (line 128) | fail() {

FILE: src/lib/default-message-id-provider.ts
  type IMessageIdProvider (line 1) | interface IMessageIdProvider {
  class DefaultMessageIdProvider (line 41) | class DefaultMessageIdProvider implements IMessageIdProvider {
    method constructor (line 44) | constructor() {
    method allocate (line 58) | allocate() {
    method getLastAllocated (line 73) | getLastAllocated() {
    method register (line 83) | register(messageId: number) {
    method deallocate (line 92) | deallocate(messageId: number) {}
    method clear (line 98) | clear() {}

FILE: src/lib/get-timer.ts
  type Timer (line 8) | interface Timer {

FILE: src/lib/shared.ts
  type DoneCallback (line 7) | type DoneCallback = (error?: Error) => void
  type GenericCallback (line 9) | type GenericCallback<T> = (error?: Error, result?: T) => void
  type VoidCallback (line 11) | type VoidCallback = () => void
  type IStream (line 13) | type IStream = (Duplex | NativeDuplex) & {
  type StreamBuilder (line 18) | type StreamBuilder = (
  type Callback (line 23) | type Callback = () => void
  type PacketHandler (line 25) | type PacketHandler = (
  type TimerVariant (line 31) | type TimerVariant = 'auto' | 'worker' | 'native'
  class ErrorWithReasonCode (line 33) | class ErrorWithReasonCode extends Error {
    method constructor (line 36) | public constructor(message: string, code: number) {
  class ErrorWithSubackPacket (line 46) | class ErrorWithSubackPacket extends Error {
    method constructor (line 49) | public constructor(message: string, packet: ISubackPacket) {
  type Constructor (line 60) | type Constructor<T = {}> = new (...args: any[]) => T
  function applyMixin (line 62) | function applyMixin(
  constant MQTTJS_VERSION (line 101) | const MQTTJS_VERSION = require('../../package.json').version

FILE: src/lib/store.ts
  type IStoreOptions (line 13) | interface IStoreOptions {
  type PacketCallback (line 20) | type PacketCallback = (error?: Error, packet?: Packet) => void
  type IStore (line 22) | interface IStore {
  class Store (line 58) | class Store implements IStore {
    method constructor (line 63) | constructor(options?: IStoreOptions) {
    method put (line 77) | put(packet: Packet, cb: DoneCallback) {
    method createStream (line 91) | createStream() {
    method del (line 129) | del(packet: Pick<Packet, 'messageId'>, cb: PacketCallback) {
    method get (line 144) | get(packet: Pick<Packet, 'messageId'>, cb: PacketCallback) {
    method close (line 158) | close(cb: DoneCallback) {

FILE: src/lib/topic-alias-recv.ts
  class TopicAliasRecv (line 6) | class TopicAliasRecv {
    method constructor (line 13) | constructor(max: number) {
    method put (line 24) | put(topic: string, alias: number): boolean {
    method getTopicByAlias (line 38) | getTopicByAlias(alias: number): string {
    method clear (line 45) | clear() {

FILE: src/lib/topic-alias-send.ts
  class TopicAliasSend (line 12) | class TopicAliasSend {
    method constructor (line 23) | constructor(max: number) {
    method put (line 39) | put(topic: string, alias: number): boolean {
    method getTopicByAlias (line 59) | getTopicByAlias(alias: number): string {
    method getAliasByTopic (line 68) | getAliasByTopic(topic: string): number | undefined {
    method clear (line 79) | clear() {
    method getLruAlias (line 90) | getLruAlias(): number {

FILE: src/lib/unique-message-id-provider.ts
  class UniqueMessageIdProvider (line 8) | class UniqueMessageIdProvider implements IMessageIdProvider {
    method constructor (line 13) | constructor() {
    method allocate (line 24) | allocate() {
    method getLastAllocated (line 34) | getLastAllocated() {
    method register (line 44) | register(messageId: number) {
    method deallocate (line 53) | deallocate(messageId: number) {
    method clear (line 61) | clear() {

FILE: src/lib/validations.ts
  function validateTopic (line 10) | function validateTopic(topic: string): boolean {
  function validateTopics (line 36) | function validateTopics(topics: string[]): string | null {

FILE: test/browser/test.js
  function testProto (line 25) | function testProto(proto, port, cb = () => { }) {

FILE: test/browser/worker.js
  constant MQTT (line 4) | const MQTT = mqtt;

FILE: test/node/abstract_client.ts
  function abstractTest (line 56) | function abstractTest(server, config, ports) {

FILE: test/node/abstract_store.ts
  function abstractStoreTest (line 6) | function abstractStoreTest(

FILE: test/node/client.ts
  method read (line 120) | read(n) {}
  method write (line 121) | write(chunk, enc, cb) {

FILE: test/node/client_mqtt5.ts
  method customHandleAcks (line 1103) | customHandleAcks(topic, message, packet, cb) {
  method customHandleAcks (line 1217) | customHandleAcks(topic, message, packet, cb) {
  method customHandleAcks (line 1263) | customHandleAcks(topic, message, packet, cb) {
  method customHandleAcks (line 1309) | customHandleAcks(topic, message, packet, cb) {
  method customHandleAcks (line 1355) | customHandleAcks(topic, message, packet, cb) {
  method customHandleAcks (line 1404) | customHandleAcks(topic, message, packet, cb) {

FILE: test/node/helpers/TeardownHelper.ts
  type ServerBuilderInstance (line 6) | type ServerBuilderInstance = ReturnType<typeof serverBuilder>
  type AddOptions (line 8) | type AddOptions = {
  type ResetOptions (line 26) | type ResetOptions = {
  type Method (line 36) | type Method =
  class TeardownHelper (line 111) | class TeardownHelper {
    method constructor (line 121) | constructor() {
    method addClient (line 129) | addClient(client: MqttClient) {
    method addServer (line 137) | addServer(server: ServerBuilderInstance) {
    method add (line 149) | add<T extends any[] = []>(
    method reset (line 169) | reset(options?: ResetOptions) {
    method closeClient (line 188) | async closeClient(client: MqttClient) {
    method closeServer (line 206) | async closeServer(server: ServerBuilderInstance) {
    method run (line 224) | async run(id: string) {
    method runAll (line 247) | async runAll() {

FILE: test/node/helpers/port_list.ts
  function getPorts (line 6) | function getPorts(i = 0) {

FILE: test/node/helpers/server.ts
  function init_server (line 4) | function init_server(PORT: number) {
  function init_secure_server (line 39) | function init_secure_server(port: number, key: string, cert: string) {

FILE: test/node/keepaliveManager.ts
  function mockedClient (line 7) | function mockedClient(keepalive: number) {

FILE: test/node/secure_client.ts
  constant KEY (line 14) | const KEY = path.join(__dirname, 'helpers', 'tls-key.pem')
  constant CERT (line 15) | const CERT = path.join(__dirname, 'helpers', 'tls-cert.pem')
  constant WRONG_CERT (line 16) | const WRONG_CERT = path.join(__dirname, 'helpers', 'wrong-cert.pem')

FILE: test/node/server.ts
  type MqttServerListener (line 6) | type MqttServerListener = (client: Connection) => void
  class MqttServer (line 13) | class MqttServer extends net.Server {
    method constructor (line 16) | constructor(listener: MqttServerListener) {
  class MqttServerNoWait (line 38) | class MqttServerNoWait extends net.Server {
    method constructor (line 41) | constructor(listener: MqttServerListener) {
  class MqttSecureServer (line 64) | class MqttSecureServer extends tls.Server {
    method constructor (line 67) | constructor(opts: TlsOptions, listener: MqttServerListener) {
    method setupConnection (line 89) | setupConnection(duplex: Duplex) {

FILE: test/node/server_helpers_for_client_tests.ts
  constant KEY (line 12) | const KEY = path.join(__dirname, 'helpers', 'tls-key.pem')
  constant CERT (line 13) | const CERT = path.join(__dirname, 'helpers', 'tls-cert.pem')
  function serverBuilder (line 23) | function serverBuilder(

FILE: test/node/socks.ts
  type State5 (line 6) | type State5 = 'new' | 'id' | 'connect'
  class MockServer5 (line 8) | class MockServer5 {
    method constructor (line 29) | constructor() {
    method start (line 36) | start(): Promise<number> {
    method port (line 46) | port(): number {
    method destroy (line 50) | destroy() {
    method destinationAddress (line 56) | destinationAddress(): string | undefined {
    method destinationPort (line 60) | destinationPort(): number | undefined {
    method parseConnect (line 115) | private parseConnect(buf: Buffer): [string, number] | undefined {

FILE: test/node/util.ts
  method transform (line 5) | transform(buf, enc, cb) {

FILE: test/node/websocket_client.ts
  function attachWebsocketServer (line 16) | function attachWebsocketServer(httpServer2) {
  function attachClientEventHandlers (line 38) | function attachClientEventHandlers(client) {
  function makeOptions (line 98) | function makeOptions(custom?: IClientOptions): IClientOptions {
  method transformWsUrl (line 129) | transformWsUrl(url, opt, client) {
  method createWebsocket (line 155) | createWebsocket(
Condensed preview — 133 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (617K chars).
[
  {
    "path": ".editorconfig",
    "chars": 147,
    "preview": "root = true\n\n[*]\nend_of_line = lf\ninsert_final_newline = true\ncharset = utf-8\nindent_style = space\nindent_size = 2\ntrim_"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.yml",
    "chars": 1424,
    "preview": "name: Bug report\ndescription: Template for bug reports\ntitle: '[Bug]: '\nlabels:\n  - bug\nbody:\n  - type: input\n    attrib"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "chars": 187,
    "preview": "blank_issues_enabled: false\ncontact_links:\n  - name: ❓ Ask a Question\n    url: https://github.com/mqttjs/MQTT.js/discuss"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "chars": 594,
    "preview": "---\nname: Feature request\nabout: Suggest an idea for this project\nlabels: enhancement\nassignees: ''\n\n---\n\n**Is your feat"
  },
  {
    "path": ".github/workflows/ISSUE_TEMPLATE/bug_report.yml",
    "chars": 1424,
    "preview": "name: Bug report\ndescription: Template for bug reports\ntitle: '[Bug]: '\nlabels:\n  - bug\nbody:\n  - type: input\n    attrib"
  },
  {
    "path": ".github/workflows/ISSUE_TEMPLATE/config.yml",
    "chars": 187,
    "preview": "blank_issues_enabled: false\ncontact_links:\n  - name: ❓ Ask a Question\n    url: https://github.com/mqttjs/MQTT.js/discuss"
  },
  {
    "path": ".github/workflows/ISSUE_TEMPLATE/feature_request.md",
    "chars": 594,
    "preview": "---\nname: Feature request\nabout: Suggest an idea for this project\nlabels: enhancement\nassignees: ''\n\n---\n\n**Is your feat"
  },
  {
    "path": ".github/workflows/browser-tests.yml",
    "chars": 821,
    "preview": "name: Browser Tests\n\non:\n  workflow_dispatch:      \n  push:\n    branches: [ main ]\n  pull_request:\n    branches: [ main "
  },
  {
    "path": ".github/workflows/electron-tests.yml",
    "chars": 650,
    "preview": "name: Electron Tests\n\non:\n  workflow_dispatch:\n  push:\n    branches: [ main ]\n  pull_request:\n    branches: [ main ]\n\njo"
  },
  {
    "path": ".github/workflows/mqttjs-test.yml",
    "chars": 1645,
    "preview": "name: MQTT.js Tests\n\non:\n  workflow_dispatch:\n    inputs:\n      logLevel:\n        description: 'Debug Filter'     \n     "
  },
  {
    "path": ".github/workflows/release-it.yml",
    "chars": 1970,
    "preview": "# #########################################################################\n# Creates a new release using `workflow_disp"
  },
  {
    "path": ".github/workflows/semantic-pr.yml",
    "chars": 350,
    "preview": "name: \"Semantic PR Title\"\n\non:\n  pull_request_target:\n    types:\n      - opened\n      - edited\n      - synchronize\n\nperm"
  },
  {
    "path": ".github/workflows/stale.yml",
    "chars": 1152,
    "preview": "name: Close inactive issues\non:\n  schedule:\n    - cron: \"30 1 * * *\"\n\njobs:\n  close-stale:\n    runs-on: ubuntu-latest\n  "
  },
  {
    "path": ".gitignore",
    "chars": 314,
    "preview": "node_modules\ncerts/*\n[._]*.s[a-w][a-z]\n[._]s[a-w][a-z]\n*.un~\nSession.vim\n.netrwhist\n*~\nnpm-debug.log\ndist/\nyarn.lock\ncov"
  },
  {
    "path": ".prettierignore",
    "chars": 47,
    "preview": "*.md\nREADME.md\n/types/\n/examples/\n/doc/\n/dist/\n"
  },
  {
    "path": ".prettierrc.js",
    "chars": 109,
    "preview": "module.exports = {\n  semi: false,\n  singleQuote: true,\n  useTabs: true,\n  tabWidth: 4,\n  endOfLine: \"lf\",\n};\n"
  },
  {
    "path": ".release-it.json",
    "chars": 492,
    "preview": "{\n  \"$schema\": \"https://unpkg.com/release-it@19/schema/release-it.json\",\n  \"github\": {\n    \"release\": true\n  },\n  \"git\":"
  },
  {
    "path": "CHANGELOG.OLD.md",
    "chars": 2118,
    "preview": "# Release History\n\n## 4.3.7\n\n### PR\n\nfix: regression from #1401 and allow CI test failures to break gitthub workflow (#1"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 66050,
    "preview": "# Changelog\n\n# [5.15.0](/compare/v5.14.1...v5.15.0) (2026-02-02)\n\n\n### Features\n\n* exported topic validation functions f"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 1231,
    "preview": "# MQTT.js is an OPEN Open Source Project\n\n-----------------------------------------\n\n## What?\n\nIndividuals making signif"
  },
  {
    "path": "DEVELOPMENT.md",
    "chars": 2964,
    "preview": "# MQTTjs Development\n\nThis document aims to help you get started with developing MQTT.js.\n\n## Release Process\n\nIn order "
  },
  {
    "path": "LICENSE.md",
    "chars": 1271,
    "preview": "The MIT License (MIT)\n=====================\n\nCopyright (c) 2015-2016 MQTT.js contributors\n------------------------------"
  },
  {
    "path": "README.md",
    "chars": 37843,
    "preview": "# ![mqtt.js](https://raw.githubusercontent.com/mqttjs/MQTT.js/137ee0e3940c1f01049a30248c70f24dc6e6f829/MQTT.js.png)\n\n![G"
  },
  {
    "path": "benchmarks/bombing.js",
    "chars": 478,
    "preview": "#! /usr/bin/env node\n\nconst mqtt = require('..')\n\nconst client = mqtt.connect({\n\tport: 1883,\n\thost: 'localhost',\n\tclean:"
  },
  {
    "path": "benchmarks/throughputCounter.js",
    "chars": 435,
    "preview": "#! /usr/bin/env node\n\nconst mqtt = require('..')\n\nconst client = mqtt.connect({\n\tport: 1883,\n\thost: 'localhost',\n\tclean:"
  },
  {
    "path": "electron-test/.gitignore",
    "chars": 1215,
    "preview": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\nlerna-debug.log*\n\n# Diagnostic reports (https://nodejs."
  },
  {
    "path": "electron-test/README",
    "chars": 27,
    "preview": "```\nnpm i\nnpm run wdio\n```\n"
  },
  {
    "path": "electron-test/forge.config.js",
    "chars": 950,
    "preview": "const { FusesPlugin } = require('@electron-forge/plugin-fuses');\nconst { FuseV1Options, FuseVersion } = require('@electr"
  },
  {
    "path": "electron-test/package.json",
    "chars": 1063,
    "preview": "{\n  \"name\": \"electron-test\",\n  \"productName\": \"electron-test\",\n  \"version\": \"1.0.0\",\n  \"description\": \"My Electron appli"
  },
  {
    "path": "electron-test/src/index.css",
    "chars": 166,
    "preview": "body {\n  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica,\n    Arial, sans-serif;\n  margin:"
  },
  {
    "path": "electron-test/src/index.html",
    "chars": 402,
    "preview": "<!DOCTYPE html>\n<html>\n  <head>\n    <meta charset=\"UTF-8\" />\n    <title>Hello World!</title>\n    <link rel=\"stylesheet\" "
  },
  {
    "path": "electron-test/src/index.js",
    "chars": 1233,
    "preview": "const { app, BrowserWindow } = require('electron');\nconst path = require('node:path');\n\nconst createWindow = () => {\n\t//"
  },
  {
    "path": "electron-test/src/renderer.js",
    "chars": 357,
    "preview": "window.$ = window.jQuery = require('jquery')\nconst path = require('node:path');\nconst mqtt = require(path.join(process.c"
  },
  {
    "path": "electron-test/test/service/server_launcher.ts",
    "chars": 1303,
    "preview": "import type { Services } from '@wdio/types'\nimport { resolve as pathResolve } from 'path'\nconst { start } = require('aed"
  },
  {
    "path": "electron-test/test/specs/test.e2e.ts",
    "chars": 670,
    "preview": "import { expect, $ } from '@wdio/globals'\n// import { join } from 'path'\nimport isBrowser from '../../../build/lib/is-br"
  },
  {
    "path": "electron-test/tsconfig.json",
    "chars": 752,
    "preview": "{\n    \"compilerOptions\": {\n        \"moduleResolution\": \"node\",\n        \"module\": \"commonjs\",\n        \"target\": \"es2022\","
  },
  {
    "path": "electron-test/wdio.conf.ts",
    "chars": 12844,
    "preview": "import { resolve as pathResolve } from 'node:path';\nimport ServerLauncher from './test/service/server_launcher'\n\nconst e"
  },
  {
    "path": "esbuild.js",
    "chars": 2866,
    "preview": "const { build } = require('esbuild')\nconst { polyfillNode } = require('esbuild-plugin-polyfill-node');\nconst { rimraf } "
  },
  {
    "path": "eslint.config.js",
    "chars": 2292,
    "preview": "const {\n    defineConfig,\n    globalIgnores,\n} = require(\"eslint/config\");\n\nconst tsParser = require(\"@typescript-eslint"
  },
  {
    "path": "example.ts",
    "chars": 1110,
    "preview": "import mqtt from './src/index'\n\nconst client = mqtt.connect('mqtt://broker.hivemq.com', {\n\tkeepalive: 3,\n\tport: 1883,\n\tr"
  },
  {
    "path": "examples/client/secure-client.js",
    "chars": 604,
    "preview": "'use strict'\n\nconst mqtt = require('../..')\nconst path = require('path')\nconst fs = require('fs')\nconst KEY = fs.readFil"
  },
  {
    "path": "examples/client/simple-both.js",
    "chars": 323,
    "preview": "'use strict'\n\nconst mqtt = require('../..')\nconst client = mqtt.connect()\n\n// or const client = mqtt.connect({ port: 188"
  },
  {
    "path": "examples/client/simple-publish.js",
    "chars": 125,
    "preview": "'use strict'\n\nconst mqtt = require('../..')\nconst client = mqtt.connect()\n\nclient.publish('presence', 'hello!')\nclient.e"
  },
  {
    "path": "examples/client/simple-subscribe.js",
    "chars": 179,
    "preview": "'use strict'\n\nconst mqtt = require('../..')\nconst client = mqtt.connect()\n\nclient.subscribe('presence')\nclient.on('messa"
  },
  {
    "path": "examples/tls client/crt.ca.cg.pem",
    "chars": 2118,
    "preview": "-----BEGIN CERTIFICATE-----\nMIIF7zCCA9egAwIBAgIJAOeJR1p1PU3qMA0GCSqGSIb3DQEBBQUAMIGNMQswCQYD\nVQQGEwJFUzERMA8GA1UECAwIWmF"
  },
  {
    "path": "examples/tls client/mqttclient.js",
    "chars": 1398,
    "preview": "'use strict'\n\n/** ************************** IMPORTANT NOTE ***********************************\n\n  The certificate used "
  },
  {
    "path": "examples/tls client/tls-cert.pem",
    "chars": 757,
    "preview": "-----BEGIN CERTIFICATE-----\nMIICATCCAWoCCQC2pNY4sfld/jANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJB\nVTETMBEGA1UECAwKU29tZS1TdGF"
  },
  {
    "path": "examples/tls client/tls-key.pem",
    "chars": 887,
    "preview": "-----BEGIN RSA PRIVATE KEY-----\nMIICXQIBAAKBgQDNcZTWZlQGovCg/V9aSJl7KmIqBYgJR02b53YkdeelAwRUHFK+\nxpEY6fNZW+BsxXGYPufn+n2"
  },
  {
    "path": "examples/vite-example/.gitignore",
    "chars": 302,
    "preview": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\npnpm-debug.log*\nlerna-debug.log*\n\nnode_modules\n.DS_Stor"
  },
  {
    "path": "examples/vite-example/README.md",
    "chars": 636,
    "preview": "# vite-example\n\nThis template should help get you started developing with Vue 3 in Vite.\n\n## Recommended IDE Setup\n\n[VSC"
  },
  {
    "path": "examples/vite-example/index.html",
    "chars": 331,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\">\n    <link rel=\"icon\" href=\"/favicon.ico\">\n    <meta"
  },
  {
    "path": "examples/vite-example/package.json",
    "chars": 508,
    "preview": "{\n  \"name\": \"vite-example\",\n  \"version\": \"0.0.0\",\n  \"private\": true,\n  \"scripts\": {\n    \"dev\": \"vite\",\n    \"build\": \"vit"
  },
  {
    "path": "examples/vite-example/src/App.vue",
    "chars": 1419,
    "preview": "<script setup>\nimport { ref } from 'vue'\nimport mqtt from 'mqtt'\n\nconst connected = ref(false)\n\nconst client = mqtt.conn"
  },
  {
    "path": "examples/vite-example/src/assets/base.css",
    "chars": 2015,
    "preview": "/* color palette from <https://github.com/vuejs/theme> */\n:root {\n  --vt-c-white: #ffffff;\n  --vt-c-white-soft: #f8f8f8;"
  },
  {
    "path": "examples/vite-example/src/assets/main.css",
    "chars": 477,
    "preview": "@import './base.css';\n\n#app {\n  max-width: 1280px;\n  margin: 0 auto;\n  padding: 2rem;\n\n  font-weight: normal;\n}\n\na,\n.gre"
  },
  {
    "path": "examples/vite-example/src/main.js",
    "chars": 118,
    "preview": "import './assets/main.css'\n\nimport { createApp } from 'vue'\nimport App from './App.vue'\n\ncreateApp(App).mount('#app')\n"
  },
  {
    "path": "examples/vite-example/vite.config.js",
    "chars": 311,
    "preview": "import { fileURLToPath, URL } from 'node:url'\n\nimport { defineConfig } from 'vite'\nimport vue from '@vitejs/plugin-vue'\n"
  },
  {
    "path": "examples/ws/aedes_server.js",
    "chars": 1155,
    "preview": "const aedes = require('aedes')()\nconst httpServer = require('http').createServer()\nconst WebSocket = require('ws')\nconst"
  },
  {
    "path": "examples/ws/client.js",
    "chars": 1220,
    "preview": "'use strict'\n\nconst mqtt = require('../../')\n\nconst clientId = 'mqttjs_' + Math.random().toString(16).substr(2, 8)\n\n// T"
  },
  {
    "path": "examples/wss/client_with_proxy.js",
    "chars": 1390,
    "preview": "'use strict'\n\nconst mqtt = require('mqtt')\nconst url = require('url')\nconst HttpsProxyAgent = require('https-proxy-agent"
  },
  {
    "path": "help/help.txt",
    "chars": 302,
    "preview": "MQTT.js command line interface, available commands are:\n\n  * publish     publish a message to the broker\n  * subscribe  "
  },
  {
    "path": "help/publish.txt",
    "chars": 1067,
    "preview": "Usage: mqtt publish [opts] topic [message]\n\nAvailable options:\n\n  -h/--hostname HOST    the broker host\n  -p/--port PORT"
  },
  {
    "path": "help/subscribe.txt",
    "chars": 1059,
    "preview": "Usage: mqtt subscribe [opts] [topic]\n\nAvailable options:\n\n  -h/--hostname HOST    the broker host\n  -p/--port PORT      "
  },
  {
    "path": "nyc.config.js",
    "chars": 353,
    "preview": "\nmodule.exports = {\n    include: [\n        'src/**',\n    ],\n    exclude: [\n        'src/bin/*',\n        'src/lib/Buffere"
  },
  {
    "path": "package.json",
    "chars": 4536,
    "preview": "{\n  \"name\": \"mqtt\",\n  \"description\": \"A library for the MQTT protocol\",\n  \"version\": \"5.15.0\",\n  \"contributors\": [\n    \""
  },
  {
    "path": "src/bin/mqtt.ts",
    "chars": 857,
    "preview": "#!/usr/bin/env node\n\n/*\n * Copyright (c) 2015-2015 MQTT.js contributors.\n * Copyright (c) 2011-2014 Adam Rudd.\n *\n * See"
  },
  {
    "path": "src/bin/pub.ts",
    "chars": 3408,
    "preview": "#!/usr/bin/env node\n\nimport { Writable } from 'readable-stream'\nimport path from 'path'\nimport fs from 'fs'\nimport conca"
  },
  {
    "path": "src/bin/sub.ts",
    "chars": 2828,
    "preview": "#!/usr/bin/env node\n\nimport path from 'path'\nimport fs from 'fs'\nimport minimist from 'minimist'\nimport help from 'help-"
  },
  {
    "path": "src/index.ts",
    "chars": 75,
    "preview": "import * as mqtt from './mqtt'\n\nexport default mqtt\nexport * from './mqtt'\n"
  },
  {
    "path": "src/lib/BufferedDuplex.ts",
    "chars": 2799,
    "preview": "import { Duplex, type Transform } from 'readable-stream'\nimport { Buffer } from 'buffer'\nimport { type IClientOptions } "
  },
  {
    "path": "src/lib/KeepaliveManager.ts",
    "chars": 2256,
    "preview": "import type MqttClient from './client'\nimport getTimer, { type Timer } from './get-timer'\nimport type { TimerVariant } f"
  },
  {
    "path": "src/lib/TypedEmitter.ts",
    "chars": 1841,
    "preview": "import EventEmitter from 'events'\nimport { applyMixin } from './shared'\n\nexport type EventHandler =\n\t// Add more overloa"
  },
  {
    "path": "src/lib/client.ts",
    "chars": 62048,
    "preview": "/**\n * Module dependencies\n */\nimport mqttPacket, {\n\ttype IAuthPacket,\n\tIConnackPacket,\n\tIDisconnectPacket,\n\tIPublishPac"
  },
  {
    "path": "src/lib/connect/ali.ts",
    "chars": 2706,
    "preview": "import { Buffer } from 'buffer'\nimport { Transform } from 'readable-stream'\nimport { type IStream, type StreamBuilder } "
  },
  {
    "path": "src/lib/connect/index.ts",
    "chars": 8020,
    "preview": "/* eslint-disable @typescript-eslint/no-require-imports */\nimport _debug from 'debug'\nimport url from 'url'\nimport MqttC"
  },
  {
    "path": "src/lib/connect/socks.ts",
    "chars": 4465,
    "preview": "import _debug from 'debug'\nimport { Duplex } from 'stream'\nimport { SocksClient, type SocksProxy } from 'socks'\nimport *"
  },
  {
    "path": "src/lib/connect/tcp.ts",
    "chars": 723,
    "preview": "import net from 'net'\nimport _debug from 'debug'\nimport { type StreamBuilder } from '../shared'\nimport openSocks from '."
  },
  {
    "path": "src/lib/connect/tls.ts",
    "chars": 1779,
    "preview": "import { type TLSSocket, connect as tlsConnect } from 'tls'\nimport net from 'net'\nimport _debug from 'debug'\nimport { ty"
  },
  {
    "path": "src/lib/connect/ws.ts",
    "chars": 7680,
    "preview": "import { Buffer } from 'buffer'\nimport Ws, { type ClientOptions } from 'ws'\nimport _debug from 'debug'\nimport { Transfor"
  },
  {
    "path": "src/lib/connect/wx.ts",
    "chars": 2812,
    "preview": "import { Buffer } from 'buffer'\nimport { Transform } from 'readable-stream'\nimport { type StreamBuilder } from '../share"
  },
  {
    "path": "src/lib/default-message-id-provider.ts",
    "chars": 2452,
    "preview": "export interface IMessageIdProvider {\n\t/**\n\t * Allocate the first vacant messageId. The messageId become occupied status"
  },
  {
    "path": "src/lib/get-timer.ts",
    "chars": 998,
    "preview": "import { clearInterval as clearI, setInterval as setI } from 'worker-timers'\nimport isBrowser, { isWebWorker, isReactNat"
  },
  {
    "path": "src/lib/handlers/ack.ts",
    "chars": 4587,
    "preview": "// Other Socket Errors: EADDRINUSE, ECONNRESET, ENOTFOUND, ETIMEDOUT.\n\nimport { type PacketHandler, ErrorWithReasonCode "
  },
  {
    "path": "src/lib/handlers/auth.ts",
    "chars": 1014,
    "preview": "import { type IAuthPacket } from 'mqtt-packet'\nimport { ErrorWithReasonCode, type PacketHandler } from '../shared'\nimpor"
  },
  {
    "path": "src/lib/handlers/connack.ts",
    "chars": 1581,
    "preview": "import { type IConnackPacket } from 'mqtt-packet'\nimport { ReasonCodes } from './ack'\nimport TopicAliasSend from '../top"
  },
  {
    "path": "src/lib/handlers/index.ts",
    "chars": 1895,
    "preview": "import handlePublish from './publish'\nimport handleAuth from './auth'\nimport handleConnack from './connack'\nimport handl"
  },
  {
    "path": "src/lib/handlers/publish.ts",
    "chars": 4339,
    "preview": "import { type IPublishPacket } from 'mqtt-packet'\nimport { type PacketHandler } from '../shared'\n\nconst validReasonCodes"
  },
  {
    "path": "src/lib/handlers/pubrel.ts",
    "chars": 840,
    "preview": "import {\n\ttype IPubcompPacket,\n\ttype IPublishPacket,\n\ttype IPubrelPacket,\n} from 'mqtt-packet'\nimport { type PacketHandl"
  },
  {
    "path": "src/lib/is-browser.ts",
    "chars": 1445,
    "preview": "// Global type declaration for Deno\ndeclare global {\n\tconst Deno: any\n}\n\nconst isStandardBrowserEnv = () => {\n\t// window"
  },
  {
    "path": "src/lib/shared.ts",
    "chars": 2741,
    "preview": "import type { Packet, ISubackPacket } from 'mqtt-packet'\nimport type { Duplex as NativeDuplex } from 'node:stream'\nimpor"
  },
  {
    "path": "src/lib/store.ts",
    "chars": 3013,
    "preview": "/**\n * Module dependencies\n */\nimport { Readable } from 'readable-stream'\nimport { type Packet } from 'mqtt-packet'\nimpo"
  },
  {
    "path": "src/lib/topic-alias-recv.ts",
    "chars": 1057,
    "preview": "/**\n * Topic Alias receiving manager\n * This holds alias to topic map\n * @param {Number} [max] - topic alias maximum ent"
  },
  {
    "path": "src/lib/topic-alias-send.ts",
    "chars": 2416,
    "preview": "/**\n * Module dependencies\n */\nimport { LRUCache } from 'lru-cache'\nimport { NumberAllocator } from 'number-allocator'\n\n"
  },
  {
    "path": "src/lib/unique-message-id-provider.ts",
    "chars": 1361,
    "preview": "import { NumberAllocator } from 'number-allocator'\nimport { type IMessageIdProvider } from './default-message-id-provide"
  },
  {
    "path": "src/lib/validations.ts",
    "chars": 1211,
    "preview": "/**\n * Validate a topic to see if it's valid or not.\n * A topic is valid if it follow below rules:\n * - Rule #1: If any "
  },
  {
    "path": "src/mqtt.ts",
    "chars": 825,
    "preview": "/*\n * Copyright (c) 2015-2015 MQTT.js contributors.\n * Copyright (c) 2011-2014 Adam Rudd.\n *\n * See LICENSE for more inf"
  },
  {
    "path": "test/browser/certs/server-cert.pem",
    "chars": 1805,
    "preview": "-----BEGIN CERTIFICATE-----\nMIIFCTCCAvGgAwIBAgIUfsHWL7ricrpv7uEMmHoDNUFt0W0wDQYJKoZIhvcNAQEL\nBQAwFDESMBAGA1UEAwwJbG9jYWx"
  },
  {
    "path": "test/browser/certs/server-key.pem",
    "chars": 3272,
    "preview": "-----BEGIN PRIVATE KEY-----\nMIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQCx1qv99lhp04i0\nc/Aj7uy7BVzenxM3sZ3SilGMAeP"
  },
  {
    "path": "test/browser/test.js",
    "chars": 2849,
    "preview": "import { expect } from '@esm-bundle/chai';\nimport mqtt from '../../'; // this will resolve to mqtt/dist/mqtt.esm.js\n\n// "
  },
  {
    "path": "test/browser/worker.js",
    "chars": 851,
    "preview": "importScripts('/dist/mqtt.js');\n\n/** @type { import('../../src') }*/\nconst MQTT = mqtt;\n\nconsole.log('worker start');\nco"
  },
  {
    "path": "test/node/abstract_client.ts",
    "chars": 105767,
    "preview": "/**\n * Testing dependencies\n */\nimport { assert } from 'chai'\nimport sinon from 'sinon'\nimport fs from 'fs'\nimport level"
  },
  {
    "path": "test/node/abstract_store.ts",
    "chars": 2978,
    "preview": "import { type IPublishPacket, type IPubrelPacket } from 'mqtt-packet'\nimport 'should'\nimport { it, beforeEach, afterEach"
  },
  {
    "path": "test/node/client.ts",
    "chars": 19561,
    "preview": "import { useFakeTimers } from 'sinon'\nimport { assert } from 'chai'\nimport { fork } from 'child_process'\nimport path fro"
  },
  {
    "path": "test/node/client_mqtt5.ts",
    "chars": 33175,
    "preview": "import { assert } from 'chai'\nimport { after, describe, it } from 'node:test'\nimport abstractClientTests from './abstrac"
  },
  {
    "path": "test/node/helpers/TeardownHelper.ts",
    "chars": 6746,
    "preview": "import type { MqttClient } from 'src'\nimport { randomUUID } from 'node:crypto'\nimport { isAsyncFunction } from 'node:uti"
  },
  {
    "path": "test/node/helpers/leaked.ts",
    "chars": 173,
    "preview": "// include this as first module when looking for leaked handles\nimport leaked from 'leaked-handles'\n\nleaked.set({\n\tfullS"
  },
  {
    "path": "test/node/helpers/port_list.ts",
    "chars": 791,
    "preview": "/**\n * Method used to get ports for testing\n * @param i Index to shift the ports by\n * @returns\n */\nexport default funct"
  },
  {
    "path": "test/node/helpers/private-csr.pem",
    "chars": 956,
    "preview": "-----BEGIN CERTIFICATE REQUEST-----\nMIICijCCAXICAQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx\nITAfBgNVBAoMGEludGV"
  },
  {
    "path": "test/node/helpers/private-key.pem",
    "chars": 1679,
    "preview": "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEA23Mhmap/uHdrE72bOjZWGIX8EXdjgT98NOQXLbs+CyxL+KkU\n4x78jHIz+ED+j9tBvQFj6wf"
  },
  {
    "path": "test/node/helpers/public-cert.pem",
    "chars": 1111,
    "preview": "-----BEGIN CERTIFICATE-----\nMIIDBjCCAe4CCQDkrq1PMPtmfzANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJB\nVTETMBEGA1UECAwKU29tZS1TdGF"
  },
  {
    "path": "test/node/helpers/public-key.pem",
    "chars": 451,
    "preview": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA23Mhmap/uHdrE72bOjZW\nGIX8EXdjgT98NOQXLbs+CyxL+KkU"
  },
  {
    "path": "test/node/helpers/server.ts",
    "chars": 1053,
    "preview": "import fs from 'fs'\nimport { MqttServer, MqttSecureServer } from '../server'\n\nexport function init_server(PORT: number) "
  },
  {
    "path": "test/node/helpers/server_process.ts",
    "chars": 168,
    "preview": "import { MqttServer } from '../server'\n\nnew MqttServer((client) => {\n\tclient.on('connect', () => {\n\t\tclient.connack({ re"
  },
  {
    "path": "test/node/helpers/tls-cert.pem",
    "chars": 1302,
    "preview": "-----BEGIN CERTIFICATE-----\nMIIDkzCCAnugAwIBAgIUKq35JCwofQRXirn9WuUcjNjGt5MwDQYJKoZIhvcNAQEL\nBQAwWTELMAkGA1UEBhMCQVUxEzA"
  },
  {
    "path": "test/node/helpers/tls-key.pem",
    "chars": 1704,
    "preview": "-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCtOByg0LeBXXIj\nAwneB5AI7WIYvsTgbCIYvqH4TI9"
  },
  {
    "path": "test/node/helpers/wrong-cert.pem",
    "chars": 757,
    "preview": "-----BEGIN CERTIFICATE-----\nMIICATCCAWoCCQDEVSSDKkcTdjANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJB\nVTETMBEGA1UECBMKU29tZS1TdGF"
  },
  {
    "path": "test/node/helpers/wrong-csr.pem",
    "chars": 603,
    "preview": "-----BEGIN CERTIFICATE REQUEST-----\nMIIBhDCB7gIBADBFMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEh\nMB8GA1UEChMYSW50ZXJ"
  },
  {
    "path": "test/node/helpers/wrong-key.pem",
    "chars": 887,
    "preview": "-----BEGIN RSA PRIVATE KEY-----\nMIICXQIBAAKBgQDIMwhVLZdKLNlPwp4VgVB8q3sJxPn8+TPDYEMmgxUuauR8d112\nOxOCzCod/OE7wWZ+DoEzGCw"
  },
  {
    "path": "test/node/keepaliveManager.ts",
    "chars": 3062,
    "preview": "import { afterEach, beforeEach, describe, it } from 'node:test'\nimport { assert } from 'chai'\nimport { useFakeTimers, sp"
  },
  {
    "path": "test/node/message-id-provider.ts",
    "chars": 3243,
    "preview": "import { assert } from 'chai'\nimport { describe, it } from 'node:test'\nimport { DefaultMessageIdProvider, UniqueMessageI"
  },
  {
    "path": "test/node/mqtt.ts",
    "chars": 9059,
    "preview": "import fs from 'fs'\nimport path from 'path'\nimport { describe, it } from 'node:test'\nimport mqtt, { type IClientOptions "
  },
  {
    "path": "test/node/mqtt_store.ts",
    "chars": 296,
    "preview": "import { describe, it } from 'node:test'\nimport { Store } from '../../src'\nimport 'should'\n\ndescribe('store in lib/conne"
  },
  {
    "path": "test/node/secure_client.ts",
    "chars": 4507,
    "preview": "import path from 'path'\nimport fs from 'fs'\nimport { assert } from 'chai'\nimport { describe, it, after } from 'node:test"
  },
  {
    "path": "test/node/server.ts",
    "chars": 2028,
    "preview": "import net from 'net'\nimport tls, { type TlsOptions } from 'tls'\nimport Connection from 'mqtt-connection'\nimport { type "
  },
  {
    "path": "test/node/server_helpers_for_client_tests.ts",
    "chars": 4364,
    "preview": "import _debug from 'debug'\n\nimport path from 'path'\nimport fs from 'fs'\n\nimport http from 'http'\nimport WebSocket from '"
  },
  {
    "path": "test/node/socks.ts",
    "chars": 10282,
    "preview": "import assert from 'assert'\nimport { type AddressInfo, createServer, type Server, type Socket } from 'net'\nimport { desc"
  },
  {
    "path": "test/node/store.ts",
    "chars": 227,
    "preview": "import { describe } from 'node:test'\nimport Store from '../../src/lib/store'\nimport abstractTest from './abstract_store'"
  },
  {
    "path": "test/node/unique_message_id_provider_client.ts",
    "chars": 762,
    "preview": "import { describe, after } from 'node:test'\nimport abstractClientTests from './abstract_client'\nimport serverBuilder fro"
  },
  {
    "path": "test/node/util.ts",
    "chars": 220,
    "preview": "import { Transform } from 'readable-stream'\n\nconst testStream = () => {\n\treturn new Transform({\n\t\ttransform(buf, enc, cb"
  },
  {
    "path": "test/node/websocket_client.ts",
    "chars": 6645,
    "preview": "import http from 'http'\nimport WebSocket from 'ws'\nimport MQTTConnection from 'mqtt-connection'\nimport assert from 'asse"
  },
  {
    "path": "tsconfig.build.json",
    "chars": 114,
    "preview": "{\n    \"extends\": \"./tsconfig.json\",\n    \"exclude\": [\"node_modules\", \"test\", \"dist\", \"build\", \"example.ts\"],\n  }\n  "
  },
  {
    "path": "tsconfig.json",
    "chars": 1134,
    "preview": "{\n\t\"$schema\": \"https://json.schemastore.org/tsconfig\",\n\t\"extends\": \"@tsconfig/node20/tsconfig.json\",\n\t\"compilerOptions\":"
  },
  {
    "path": "web-test-runner.config.mjs",
    "chars": 2032,
    "preview": "// Docs: https://modern-web.dev/docs/test-runner/cli-and-configuration/\nimport { playwrightLauncher } from '@web/test-ru"
  }
]

About this extraction

This page contains the full source code of the mqttjs/MQTT.js GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 133 files (535.2 KB), approximately 166.5k tokens, and a symbol index with 268 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!