All notable changes to this project are documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- The paced consume engine (
KeyValue.watchPaced/watchAllPaced,StreamContext.createOrderedPacedConsumer/getPacedConsumerContext) mistook the server's routine expiry of an idle pull for an early pull terminus: the local window deadline (armed at publish) always fired before the server'sexpiresInclock (started at receipt), so the server's408landed at the head of the next window and tripped the 500 ms early-terminus guard — a non-draining sleep and a redundant second pull per idle window. Statuses are now matched to the pull they answer via jnats's per-pull reply subjects, and stale ones are skipped. No API or configuration change; the callback engine is unaffected.
- Pure KV key validation on the
KeyValuecompanion object:validateKey(write/read keys) andvalidateKeyWildcardAllowed(watch/keysfilter patterns), returningEither[InvalidKeyError, Unit]with the offending key and the jnats reason. Both delegate to the jnats validators (KV key grammar plus strict subject grammar), so callers can validate keys before a write instead of catching and sniffingIllegalArgumentExceptionfromput.
KeyValue.keysDetailed(...)(three overloads mirroringkeys) returningKeysResult(keys, warmup), which exposes theWarmup.Resultof the underlying warmup. This lets callers detect when a key listing was cut short by the warmuptimeout(Warmup.Result.Timeout) versus completed fully (Warmup.Result.Success).
KeyValue.keys(...)could silently return a partial key set when warmup hit itstimeoutbefore all pending messages were drained, with no signal to the caller — a silent-data-loss hazard for anylist-style operation built onkeys. Fixed additively (non-breaking):keysbehaviour is unchanged and it now delegates tokeysDetailed; callers that need completeness guarantees should switch tokeysDetailedand inspectwarmup(e.g. raise, retry with a longer timeout, or return partial-with-a-flag). No existing caller breaks. See Option A inTASK.md.