feat(client): add LMOVEM and BLMOVEM commands#3340
Open
nkaradzhov wants to merge 4 commits into
Open
Conversation
Add LMOVEM and its blocking variant BLMOVEM to move multiple elements between two lists in a single command, closing the gap where only one element could be moved (LMOVE/BLMOVE) while the pop family already supported many. Options are modeled as a discriminated union so COUNT and EXACTLY are mutually exclusive at the type level, each with an optional OBO|BULK ordering. Reply is always an array of moved elements (destination order) or null when nothing moved. Single-slot multi-key: specs use hash-tag collocated keys for cluster. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add isVersionGreaterThanHook([8, 10]) so behavior tests run only on Redis 8.10+, and add @SInCE 8.10 to the LMOVEM/BLMOVEM registry JSDoc. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Drop the single-caller parseLMoveMArguments helper; BLMOVEM cannot reuse it (timeout sits mid-args), so it was dead abstraction. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Extract parseLMoveMOptions helper shared by LMOVEM and BLMOVEM - Correct BLMOVEM JSDoc blocking-semantics wording (COUNT unblocks at 1) - Add @see redis.io links to LMOVEM/BLMOVEM entries - Cover no-options single-element reply, COUNT clamping, EXACTLY-too-few Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
nkaradzhov
marked this pull request as ready for review
July 14, 2026 13:27
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
Reviewed by Cursor Bugbot for commit ef8c325. Configure here.
| EXACTLY: 3, | ||
| ORDER: 'BULK' | ||
| }) | ||
| ); |
There was a problem hiding this comment.
EXACTLY test expects rejection
Medium Severity
The integration test for EXACTLY with too few source elements uses assert.rejects, but the PR and LMoveMOptions JSDoc describe moving nothing as a successful no-op with a null reply, not a command error.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit ef8c325. Configure here.
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.


This pull request adds the
LMOVEMandBLMOVEMcommands to@redis/client, closing the gap where only a single element could be moved between lists (LMOVE/BLMOVE) while the pop family already moved many.LMOVEM source destination <LEFT|RIGHT> <LEFT|RIGHT> [<COUNT|EXACTLY> count <OBO|BULK>]— moves up to (COUNT) or exactly (EXACTLY) N elements from one end of the source list to one end of the destination; reply is always an array of moved elements (destination order), ornullwhen nothing moved.BLMOVEM— blocking variant, same options plus atimeout(seconds,0= forever).API
Options are modeled as a discriminated union —
{ COUNT: number, ORDER?: 'OBO' | 'BULK' }XOR{ EXACTLY: number, ORDER?: 'OBO' | 'BULK' }— soCOUNT/EXACTLYare mutually exclusive at the type level, andORDER(OBO = stack/reversed, BULK = queue/preserved) only applies when a count is given. Omitting options moves a single element, still as an array reply. Both raw and camelCase aliases are exposed (LMOVEM/lMoveM,BLMOVEM/blMoveM).Considerations
LMOVE/BLMOVE) so the reply type never changes with arguments.{tag}prefixes.LMOVEM); argument serialization is type-checked and asserted viaparseArgs.🤖 Generated with Claude Code
Note
Low Risk
Additive client command definitions and tests only; no changes to existing LMOVE/BLMOVE behavior or core connection logic.
Overview
Adds Redis 8.10 list commands
LMOVEMandBLMOVEMto@redis/client, exposing bulk move between two lists (alongside existing single-elementLMOVE/BLMOVE).lMoveM/LMOVEMmoves one or more elements between source and destination list ends; replies are always a string array (ornullwhen nothing moves), including the default single-element case. OptionalLMoveMOptionsare a typed union:COUNT(up to N, clamped) orEXACTLY(all-or-nothing), plus optionalORDEROBOvsBULK. SharedparseLMoveMOptionsserializes the trailing Redis args for both commands.blMoveM/BLMOVEMmirrors that API with a blocking timeout before the options tail and reusesLMOVEM’s reply typing. Both are registered in the command index with raw and camelCase aliases.Specs gate on version ≥ 8.10, assert
parseArgswire format, and include integration tests (cluster-safe{tag}keys) for ordering, empty source, timeout, andEXACTLYfailure when the source is too short.Reviewed by Cursor Bugbot for commit ef8c325. Bugbot is set up for automated code reviews on this repo. Configure here.