• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

moscajs / aedes-persistence / 35065058346
97%
master: 97%

Build:
Build:
LAST BUILD BRANCH: main
DEFAULT BRANCH: master
Ran 16 Sep 2026 06:44AM UTC
Jobs 1
Files 6
Run time 1min
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

16 Sep 2026 06:43AM UTC coverage: 96.887% (+0.05%) from 96.835%
35065058346

push

github

web-flow
feat!: add cleanIncoming(client) to drop QoS 2 dedup state on session end (#111)

* feat!: add cleanIncoming(client) to drop QoS 2 dedup state on session end

The inbound QoS 2 dedup store has no per-client cleanup entry point.
incomingStorePacket writes a packet keyed by (clientId, messageId),
incomingDelPacket is the only deletion path, and it is driven by the PUBREL
handler. A client that publishes QoS 2 and disconnects before completing the
handshake leaves a record behind, keyed by its clientId, with no way to remove
it.

That gap stops aedes satisfying MQTT 3.1.1 [MQTT-3.1.2-6], which requires the
server to discard all session state when a client connects with cleanSession=1.
Subscriptions have cleanSubscriptions; incoming had nothing. Prompted by
GHSA-p8r9-qf8w-p73r against aedes; details on publication.

cleanIncoming(client) removes every stored incoming packet for client.id. It is
named for the clean* family rather than the incoming* one: incoming*(client,
packet) is per-packet QoS 2 message flow, this is session teardown taking only a
client, exactly like cleanSubscriptions. The shape is also the one a real store
wants — a single delete-by-client, not a loop over per-messageId deletes.

BREAKING CHANGE: cleanIncoming is required. abstract.js tests it
unconditionally, so an implementation that bumps its aedes-persistence dev
dependency without adding the method fails its own conformance run, and
types/index.d.ts declares it non-optional on AedesPersistence. aedes
feature-detects it and skips it when absent, so an older persistence keeps
working rather than crashing. Downstream: mongodb, redis, level, nedb, sqlite.

CallBackPersistence no longer advertises cleanIncoming when the async
implementation it wraps lacks it. Without that, a consumer's feature detection
passes on the wrapper and the bare delegation throws synchronously — mongodb,
redis and level all wrap their own async persistence in this class, so every one
of those brokers would h... (continued)

395 of 425 branches covered (92.94%)

Branch coverage included in aggregate %.

98 of 99 new or added lines in 4 files covered. (98.99%)

2593 of 2659 relevant lines covered (97.52%)

331.95 hits per line

Uncovered Changes

Lines Coverage ∆ File
1
99.5
-0.11% abstract.js
Jobs
ID Job ID Ran Files Coverage
1 35065058346.1 16 Sep 2026 06:44AM UTC 6
96.89
GitHub Action Run
Source Files on build 35065058346
  • Tree
  • List 6
  • Changed 4
  • Source Changed 0
  • Coverage Changed 4
Coverage ∆ File Lines Relevant Covered Missed Hits/Line Branch Hits Branch Misses
  • Back to Repo
  • a7d9bd3b on github
  • Prev Build on main (#28378143903)
  • Next Build on main (#35065214487)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc