Skip to content

feat: take aedes 1.1.1 (D-021 obligation (1), D-031) - #15

Merged
nzneit merged 7 commits into
mainfrom
aedes-1x
Aug 11, 2026
Merged

nzneit merged 7 commits into
mainfrom
aedes-1x

Conversation

@nzneit

@nzneit nzneit commented Aug 10, 2026

Copy link
Copy Markdown
Owner

Summary

Discharges the last of D-021's three deferred range changes: aedes ^0.51.3 → ^1.1.1, landed exactly under D-026's condition (own branch/PR/decision entry + an R-033 rehearsal re-run) and along D-024's de-risked path.

Migration — precisely the delta D-024's ten-check Bun probe recorded:

  • import { Aedes } (the 1.x default export is a function whose body throws a migration error)
  • await aedes.listen() at the top of start() before either port listener opens — persistence setup became async and moved out of the constructor, so this.persistence exists only post-listen (getState was already a post-start surface; the AedesWithPersistence narrowing stays, since 1.x still types persistence only on the options)
  • D-024's bare node:net tcp listener and the hand-built ws listener: no change

Defaults: taken unchanged. The measured diff vs 0.51.3 is exactly two options:

  • drainTimeout: 60000 — arms only on socket backpressure (unref'd timer) and disconnects a client whose socket stays undrained 60s; no clean path gains latency, aedes.close() unaffected
  • maxTopicLevels: 100 — not a new limit: a 101-level publish on 0.51.3 threw qlobber's synchronous too many words (the bundled matcher already capped at 100); 1.1.1 fails the same input cleanly via the publish callback (topic has too many levels), so broker.emit rejects legibly at the same ceiling

maxClientsIdLength/keepaliveLimit unchanged, so the connect surface D-026 measured does not move. Lockfile slims: eight utility deps dropped; aedes-persistence 10.3.1 + mqemitter 7.1.0 in; persistence backends are optional peers, not installed.

Verification

  • Full gate set exits 0: check-docs, lint, typecheck, demo-app:build, bun test 568 pass / 0 fail — including src/broker/connect-profile.test.ts, the D-026 closure pin (MQTT 3.1.1 over ws, non-root path, no auth, retained receipt on subscribe, persistent session at keepalive 30, QoS 0/1 both ways)
  • R-033 rehearsal re-run: green — the demo-app.md §9 walk on the bumped broker in Chromium and Firefox both: checklist all-green, command chain reacts, both break buttons caught, zero sent-vs-seen discrepancies (manual by design)

Docs

  • DECISIONS.md: D-031 (measurements, the defaults analysis, the rehearsal record)
  • AGENTS.md: status updated — all three D-021 deferred range changes now discharged

nzneit added 7 commits August 10, 2026 08:40
The measured migration delta from D-024's probe, verbatim: the named import
(1.x's default export throws a migration error), and await aedes.listen()
in start() before the port listeners open (persistence setup became async
and moved out of the constructor). The node:net tcp listener was already
D-024's. Defaults diff vs 0.51.3 is two options: drainTimeout 60000 (arms
only on socket backpressure, unref'd, disconnects a frozen client after
60s — no clean-path latency) and maxTopicLevels 100 (qlobber already threw
'too many words' past 100 levels on 0.51; 1.x fails it cleanly at the
gate). Suite 568/0 exit 0, all gates green.
…-dependent mechanisms

aedes 1.x moves persistence setup into listen(), which narrows the broker's
pre-start surface: getState rejected with a raw TypeError and emit failed
inconsistently by QoS (TypeError for QoS>0/retained, silent success for
QoS-0 non-retained). Both now reject with one legible error, pinned by a
unit test. D-031's maxTopicLevels bullet is corrected to what the review
measured (0.51 sync-threw only at QoS 0; at emit's default QoS 1 it hung
the callback with an uncaught async throw), extended to the subscribe-side
failure mode, and gains the QoS-2 delivery-timing note.
…ve panel

A second start() on aedes 1.x wipes the retained store and orphans the
heartbeat interval before the port bind rejects, and start-after-stop
resolves into a zombie broker; re-entry now rejects on entry, pinned
including retained-state survival. D-031's subscribe-side parenthetical is
corrected to the panel's measurement (process-fatal on both runtimes; the
'survivable under Bun' read was a test-runner artifact), the lockfile
sentence now says six of eight leave the lock, the suite count reflects the
branch head, the flag-placement and stop-no-reset residuals are stated, and
REQUIREMENTS.md's R-033 parenthetical records the re-run as done.
@nzneit
nzneit merged commit b3eb720 into main Aug 11, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant