Repository navigation
v0.4.0: bug fixes, batch ops, scoring, streaming, serializers and retention - #5
Merged
Merged
Conversation
… and retention Bug fixes: - ItemRepository: replace blocking KEYS with SCAN (fanned out to all masters on Redis Cluster), avoid CROSSSLOT MGET/DEL on Cluster, match repository names literally (glob escaping), stop colliding with the index key of a SortedItemRepository with the same name, stable ordered pagination - SortedItemRepository: atomic MULTI writes/deletes (ordered, safe writes on Cluster), drop redundant hexists/zrem round trips, wall-clock monotonic scores instead of process.hrtime (meaningless across processes, lost precision) - Both: real total count on out-of-range pages, read methods no longer return hidden nulls, validate page/pageSize/n/TTL/id instead of silently selecting (or deleting) the whole repository - build script no longer fails without an existing dist/ Features: - Batch operations: setMany, getByIds, deleteByIds - Sorted repository scoring and ordering: explicit score, keepScore, desc pagination, infinite bounds plus offset/limit/order on getItemsByScore - Streaming via iterate() async iterators - Constructor options: pluggable serializer, Cluster hashTag for atomic transactions on Redis Cluster - TTL and retention: getTtl/expire/persist, deleteByScore, trimToSize, maxItems Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JLbcuU2UWtjZCuWZa1QTkE
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JLbcuU2UWtjZCuWZa1QTkE
package-lock.json was generated on darwin-arm64 and only records that platform's @rometools/cli package, so the bun install in CI skipped the linux-x64 binary and `bun run lint` failed with "Cannot find module '@rometools/cli-linux-x64/rome'". bun.lock takes precedence for bun and records every platform's binary; all dependency versions match package-lock.json. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JLbcuU2UWtjZCuWZa1QTkE
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Minor release
0.4.0. It fixes functional bugs in both repositories and adds five features. Three independent reviews (Redis internals, API/developer experience, reliability/testing) shaped the plan.Bug fixes
ItemRepository
SCANinstead ofKEYS, which blocked the server. On Redis Cluster the scan runs on every master; before, it only reached one node.MGET/DELon Cluster, which failed withCROSSSLOTerrors.*acted as a glob, sodeleteAll()could delete other repositories' data.SortedItemRepositorywith the same name. That key showed up as anullentry, madecountone too high, anddeleteAll()deleted it.SortedItemRepository
MULTItransaction. On Cluster without a hash tag they run in a safe order instead: data before index on writes, index before data on deletes.setno longer makes the extrahexists/zremround trips.process.hrtime, which can't be compared across processes or restarts and loses precision after about 104 days of uptime.Both
countinstead of0.nulls.page,pageSize,n, TTL andidare validated and throw aRangeErrororTypeErrorwhen invalid. Before,pageSize = 0orn = 0selected the whole repository, and withdeletePagedeleted it.buildscript no longer fails whendist/doesn't exist.Features
setMany,getByIds(results keep the input order,nullfor missing ids) anddeleteByIds.set(item, { score, keepScore })getPaginated(page, size, 'desc')getItemsByScore(min, max, { offset, limit, order }), which also accepts'-inf'/'+inf'boundsiterate({ batchSize, order })async iterators, so you can walk a repository without loading all of it.serializer(MessagePack stays the default)hashTagfor atomic transactions on Redis ClustergetTtl,expireandpersistonItemRepository;deleteByScore,trimToSizeand amaxItemscap onSortedItemRepository.Behavior changes
IItemRepositoryandISortedItemRepositorygain required methods, so custom implementations of these interfaces must add them.hrtimescores may sort out of order relative to new ones.n, TTL or empty-id arguments now throw instead of doing something surprising.keepScore: trueto keep its position.Known limitations
acan still see keys of repositorya:b: a key likeitems:a:b:1could belong to either. Fixing this needs a new key layout.deletePage,deleteByScoreandtrimToSizeread the matching ids, then delete them, so they can race with concurrent writers.Testing
bun run test: 51 pass, including 27 new tests. Of the new tests, 25 fail on the previous code. The other two (concurrent set/delete consistency, ordering across repository instances) pass on both versions, because those problems don't reproduce inside a single test process.crypto.randomUUID().tsc --noEmit,bun run lintandbun run buildare clean.hashTag.Generated by Claude Code