Skip to content

feat(client): add LMOVEM and BLMOVEM commands#3340

Open
nkaradzhov wants to merge 5 commits into
redis:masterfrom
nkaradzhov:move-between-lists
Open

feat(client): add LMOVEM and BLMOVEM commands#3340
nkaradzhov wants to merge 5 commits into
redis:masterfrom
nkaradzhov:move-between-lists

Conversation

@nkaradzhov

@nkaradzhov nkaradzhov commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator

This pull request adds the LMOVEM and BLMOVEM commands 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), or null when nothing moved.
  • BLMOVEM — blocking variant, same options plus a timeout (seconds, 0 = forever).

API

Options are modeled as a discriminated union — { COUNT: number, ORDER?: 'OBO' | 'BULK' } XOR { EXACTLY: number, ORDER?: 'OBO' | 'BULK' } — so COUNT/EXACTLY are mutually exclusive at the type level, and ORDER (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

  • New commands (not options on LMOVE/BLMOVE) so the reply type never changes with arguments.
  • Single-slot multi-key: source and destination must be hash-tag collocated in cluster mode; specs use {tag} prefixes.
  • Commands are unreleased upstream, so behavior tests were authored but not executed locally (no server build exposing LMOVEM); argument serialization is type-checked and asserted via parseArgs.

🤖 Generated with Claude Code


Note

Low Risk
Additive command definitions and exports following existing LMOVE/BLMOVE patterns; no changes to auth, data migration, or existing command behavior.

Overview
Adds Redis 8.10 list commands LMOVEM and BLMOVEM to @redis/client, exposing lMoveM / blMoveM alongside the existing single-element LMOVE / BLMOVE APIs.

LMOVEM moves one or more elements between lists with optional COUNT (up to N) or EXACTLY (all-or-nothing), plus OBO / BULK ordering when a count is set. Replies are typed as an array of moved strings or null when nothing moves. BLMOVEM is the blocking variant with the same options and a timeout before the optional tail args; parseLMoveMOptions is shared so COUNT/EXACTLY/ORDER serialization stays consistent.

Commands are registered in the command index with JSDoc. New specs cover parseArgs wire format and integration cases (empty source, ordering, clamping, EXACTLY failure), gated on server version 8.10.

Reviewed by Cursor Bugbot for commit 05594ba. Bugbot is set up for automated code reviews on this repo. Configure here.

@nkaradzhov
nkaradzhov marked this pull request as ready for review July 14, 2026 13:27
@nkaradzhov
nkaradzhov requested a review from PavelPashov July 14, 2026 13:28

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

Reviewed by Cursor Bugbot for commit ef8c325. Configure here.

Comment thread packages/client/lib/commands/LMOVEM.spec.ts
nkaradzhov and others added 4 commits July 21, 2026 21:50
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
nkaradzhov force-pushed the move-between-lists branch from ef8c325 to 29581f7 Compare July 21, 2026 18:51
The spec expected LMOVEM with EXACTLY greater than the source list
length to reject with a server error, but Redis 8.10 replies with null
and moves nothing. Assert a null reply instead and document the null
reply in the EXACTLY option JSDoc.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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