v5.2.8
Storage engine
-
A commit parked on a write intent that was never released could wedge the worker thread (#2466). rocksdb-js 2.8.0 bounds the coordinated-retry park with
ROCKSDB_JS_PARK_TIMEOUT_MS(HarperFast/rocksdb-js#744), so a commit waiting on an intent that never gets released now wakes and consumes a retry attempt instead of never settling. Previously that wait had no upper bound, and the thread holding it stayed parked.The root
msgpackrpin moves to 2.0.6 alongside it.check-shrinkwrap-pins.mjsrequires the root pin to equal rocksdb-js's own so that one module instance — and therefore one structure and extension registry — is shared, and rocksdb-js 2.8.0 depends on msgpackr 2.0.6. Over 2.0.5 that is a single decode-hardening change: array and map lengths that exceed the remaining source data are now rejected rather than trusted. The lockfile loses the nested msgpackr copy under rocksdb-js accordingly. This is the versionmainalready runs.
Replication & subscriptions
-
RocksDB subscription listeners dropped every source-fill event as out-of-order, and catch-up replayed patch entries with no value (#2445, backport of #2409). A source fill writes with the transaction's commit timestamp, but the RocksDB transaction-log reader overwrote the decoded record version with the log key. The subscription listener's staleness check then compared a record version against a log position and discarded the event. The same reader left
auditRecord.localTimeunset, so collectionstartTimereplay calledgetValue()with no reconstruction time and delivered patch entries withvalue: undefined.The entry's own version is now exposed as
AuditRecord.recordVersion, surviving the log-key override, and the staleness check compares record versions; raw same-thread aftercommit entries are stamped with the same two clocks the decoded path reports.versiondeliberately stays the log key — replication resume relies onversion === log key— so cursor advancement, transaction grouping, and resume semantics are unchanged. Only the RocksDB engine was affected; LMDB was already correct.
MCP
-
Every table Resource manufactured a
create_*MCP tool, whether or not it had a real create verb (#2405, fixes #1945).detectVerbs()'s create check wastypeof p.post === 'function' || typeof p.update === 'function', butResource.prototypedefines a basepost()(resources/Resource.ts), so the first clause was true for every Resource subclass regardless of what it overrode — making the check unconditionally true and theupdateclause moot. Agents were offered create tools that had nothing behind them.The check now reuses
toolRegistry.ts'shasClassLevelVerbs(), which identity-compares againstResource.prototypeand so counts only a real override, or the implicitupdate()override thatTable.ts's write path relies on. An instance-levelcreate()override counts directly as well:Resource.post'sloadAsInstance === falsebranch dispatches straight to it, bypassing bothpostandupdate, and a resource built that way would otherwise have silently lost itscreate_tool.
Also in this release
- Test coverage for the two fixes above: a transaction-broadcast grouping test for the subscription path, a catch-up regression test pinning the client-observable "a replayed patch carries a full value" contract on both storage engines (#2444), and an MCP fixture corrected to match
Table.ts's actual shape (it definescreate()alongsideupdate()).
Full Changelog: v5.2.7...v5.2.8