componentized/directory

componentized:valkey

interface dev

A WASM component client for Valkey (and Redis).

interface types componentized:valkey/types@0.3.0-dev

The types of the package's interfaces, their stable public names.

The other interfaces use these types under names of their own, which may change, e.g. renamed to avoid clashing with a function for a new command. Refer to a type through this interface for a name that does not change.

Types

type resp-errorsince 0.3.0-dev

resp An encoding error, converting RESP values to or from bytes.

  • string

type integersince 0.3.0-dev

  • s64

type doublesince 0.3.0-dev

  • f64

type bytessince 0.3.0-dev

Raw bytes, e.g. a bulk string, which Valkey keeps as given, UTF-8 or not.

  • list<u8>

variant string-or-bytessince 0.3.0-dev

  • string: string

    utf-8 decoded bytes.

  • bytes: bytes

    bytes that cannot be represented as a utf-8 string.

type resp-nested-valuesince 0.3.0-dev

Values nested within an aggregate type. Since WIT types are not allowed to depend on themselves, nested values are stored as encoded RESP.

  • list<u8>

variant resp-valuesince 0.3.0-dev

variant error-codesince 0.3.0-dev

connection The errors of a connection and of every command interface.

  • closed: option<string>

    The transport closed while a reply was outstanding, or before the command was sent. Holds the transport's error when it did not close gracefully.

  • client: string

    Client errors are semantic issues with input/output values, e.g. a reply that does not have the shape the command expects.

  • resp: resp-error

    RESP errors are encoding issues converting values to/from bytes.

  • server: string-or-bytes

    Server errors are Error or BulkError RESP values returned directly from the server. An Error is a string, a BulkError a string when it is UTF-8, bytes otherwise.

  • lagged

    The reader of a stream fell too far behind and its stream was closed, rather than holding up the connection. What the stream missed is lost.

variant subscription-targetsince 0.3.0-dev

What a subscription is subscribed to, see connection.subscription.

  • channel: string

    A channel, see SUBSCRIBE.

  • pattern: string

    A pattern of channels, see PSUBSCRIBE.

  • shardchannel: string

    A shard channel, see SSUBSCRIBE.

record subscription-messagesince 0.3.0-dev

A message published to a channel.

A subscription with overlapping targets, e.g. a channel and a pattern matching it, receives a message once for each target.

  • payload: string-or-bytes

    The message as published, UTF-8 or not.

  • channel: string

    The channel the message was published to: a channel, published with PUBLISH, or a shard channel, published with SPUBLISH. Channels and shard channels are separate, a channel and a shard channel of the same name are not the same. target tells them apart, a shardchannel target for a shard channel, a channel or pattern target otherwise.

  • target: subscription-target

    The subscription's target that matched the channel, the channel itself, or a pattern matching it.

enum unsubscribe-reasonsince 0.3.0-dev

Why a target is no longer subscribed to.

  • requested

    By the subscription, e.g. its unsubscribe.

  • by-server

    By the server on its own, e.g. the slot of a shard channel moved to another node.

  • reset

    By connection.reset.

variant subscription-eventsince 0.3.0-dev

What a subscription's stream carries, in the order it happened.

record duration-secondssince 0.3.0-dev

shared by the commands A duration in whole seconds, e.g. EX seconds.

  • ex: u64

record duration-millisecondssince 0.3.0-dev

A duration in whole milliseconds, e.g. PX milliseconds.

  • px: u64

record connect-optssince 0.3.0-dev

Options for establishing a connection.

  • auth: option<tuple<string, string>>

    The username and password to authenticate with.

  • client-name: option<string>

    The name of the connection, see CLIENT SETNAME.

  • keep-alive-interval: option<duration-milliseconds>

    Enables keep-alive pings at this interval, see connection.set-keep-alive.

record unix-time-secondssince 0.3.0-dev

A point in time as whole seconds since the Unix epoch, e.g. EXAT unix-time-seconds.

  • exat: s64

record unix-time-millisecondssince 0.3.0-dev

A point in time as whole milliseconds since the Unix epoch, e.g. PXAT unix-time-milliseconds.

  • pxat: s64

variant cursorsince 0.3.0-dev

Where an incremental iteration continues from, e.g. with HSCAN.

A scan returns the cursor to resume from, always resume, none once the scan is complete. Pass it to the next call until then.

  • start

    Starts a new scan, the cursor 0.

  • resume: string

    Continues a scan from the opaque cursor the previous call returned, 0 fails with a client error, use start.

enum ttl-modesince 0.3.0-dev

The condition for setting an expiration, e.g. with EXPIRE or HEXPIRE.

  • nx

    Set expiration only when the field has no expiration.

  • xx

    Set expiration only when the field has an existing expiration.

  • gt

    Set expiration only when the new expiration is greater than current one.

  • lt

    Set expiration only when the new expiration is less than current one.

variant ttl-replysince 0.3.0-dev

The remaining time to live of a key or hash field, to the second, see ttl and httl.

  • does-not-exist

    -2: the key does not exist, or for a hash field, the field or the hash does not exist.

  • no-expiration

    -1: the key or field exists, but has no expiration.

  • expires-in: duration-seconds

    The time until it expires.

type httl-replysince 0.3.0-dev

The remaining time to live of a field, see httl.

variant pttl-replysince 0.3.0-dev

The remaining time to live of a key or hash field, to the millisecond, see pttl and hpttl.

  • does-not-exist

    -2: the key does not exist, or for a hash field, the field or the hash does not exist.

  • no-expiration

    -1: the key or field exists, but has no expiration.

  • expires-in: duration-milliseconds

    The time until it expires.

type hpttl-replysince 0.3.0-dev

The remaining time to live of a field, see hpttl.

variant expiretime-replysince 0.3.0-dev

When a key or hash field expires, to the second, see expiretime and hexpiretime.

  • does-not-exist

    -2: the key does not exist, or for a hash field, the field or the hash does not exist.

  • no-expiration

    -1: the key or field exists, but has no expiration.

  • expires-at: unix-time-seconds

    The time at which it expires.

type hexpiretime-replysince 0.3.0-dev

The expiration time of a field, see hexpiretime.

variant pexpiretime-replysince 0.3.0-dev

When a key or hash field expires, to the millisecond, see pexpiretime and hpexpiretime.

  • does-not-exist

    -2: the key does not exist, or for a hash field, the field or the hash does not exist.

  • no-expiration

    -1: the key or field exists, but has no expiration.

  • expires-at: unix-time-milliseconds

    The time at which it expires.

type hpexpiretime-replysince 0.3.0-dev

The expiration time of a field, see hpexpiretime.

record limitsince 0.3.0-dev

A range of a sorted result, LIMIT offset count.

  • offset: integer

    The number of elements skipped.

  • count: integer

    The maximum number of elements returned, negative for all of them.

enum sort-ordersince 0.3.0-dev

  • asc

    ascending, smallest to largest.

  • desc

    descending, largest to smallest.

variant acl-dryrun-resultsince 0.3.0-dev

admin commands Whether a user may run a command, see acl-dryrun.

  • allowed

    The user may run the command.

  • denied: string

    The user may not run the command, and why.

record acl-log-entrysince 0.3.0-dev

A security event, a command or authentication the rules denied, see acl-log.

  • count: integer

    The number of events like this one, within 60 seconds of each other.

  • reason: string

    What was denied, e.g. command, key, channel or auth.

  • context: string

    Where it was denied, e.g. toplevel, multi or lua.

  • object: string

    The command, key or channel that was denied.

  • username: string
  • age-seconds: double

    The seconds since the latest of these events.

  • client-info: string

    The connection, in the format of CLIENT LIST.

  • entry-id: option<integer>

    The ID of the entry, since Valkey 7.2.

  • timestamp-created: option<unix-time-milliseconds>

    When the first of these events happened, since Valkey 7.2.

  • timestamp-last-updated: option<unix-time-milliseconds>

    When the latest of these events happened, since Valkey 7.2.

enum bgsave-operationsince 0.3.0-dev

What BGSAVE does.

  • schedule

    SCHEDULE: saves once the rewrite of the append-only file in progress is done.

  • cancel

    CANCEL: cancels the save in progress, or scheduled.

enum client-typesince 0.3.0-dev

The type of a connection, for the client-filter.

  • normal

    normal

  • primary

    master: the connection to the primary of a replica.

  • replica

    replica

  • pubsub

    pubsub

variant client-filtersince 0.3.0-dev

A filter of connections, for CLIENT KILL and CLIENT LIST.

  • id: list<integer>

    ID client-id [ client-id ... ]

  • type: client-type

    TYPE

  • user: string

    USER username

  • addr: string

    ADDR ip:port: the address of the client.

  • laddr: string

    LADDR ip:port: the address of the server the client connected to.

  • skipme: bool

    SKIPME YES | NO: whether to skip this connection, yes by default for CLIENT KILL.

  • maxage: duration-seconds

    MAXAGE: connections older than the time.

  • name: string

    NAME

  • idle: duration-seconds

    IDLE: connections idle for at least the time.

  • flags: string

    FLAGS: connections with all the flags, e.g. N.

  • lib-name: string

    LIB-NAME

  • lib-ver: string

    LIB-VER

  • db: integer

    DB

  • capa: string

    CAPA: connections with the capability, e.g. redirect.

  • ip: string

    IP

  • not-id: list<integer>

    NOT-ID client-id [ client-id ... ]

  • not-type: client-type

    NOT-TYPE

  • not-user: string

    NOT-USER

  • not-addr: string

    NOT-ADDR

  • not-laddr: string

    NOT-LADDR

  • not-name: string

    NOT-NAME

  • not-flags: string

    NOT-FLAGS

  • not-lib-name: string

    NOT-LIB-NAME

  • not-lib-ver: string

    NOT-LIB-VER

  • not-db: integer

    NOT-DB

  • not-capa: string

    NOT-CAPA

  • not-ip: string

    NOT-IP

enum client-pause-modesince 0.3.0-dev

Which commands CLIENT PAUSE suspends.

  • write

    WRITE: commands that may write.

  • all

    ALL: every command, the default.

enum client-unblock-typesince 0.3.0-dev

How CLIENT UNBLOCK unblocks a connection.

  • timeout

    TIMEOUT: as if the command timed out, the default.

  • error

    ERROR: with an UNBLOCKED error.

variant cluster-bumpepoch-resultsince 0.3.0-dev

The outcome of CLUSTER BUMPEPOCH.

  • bumped: integer

    BUMPED: the config epoch was advanced, to this one.

  • still: integer

    STILL: the config epoch is already the greatest in the cluster, this one.

enum cluster-failover-modesince 0.3.0-dev

How CLUSTER FAILOVER fails over.

  • force

    FORCE: without the agreement of the primary, which may be down.

  • takeover

    TAKEOVER: without the agreement of the primary or the rest of the cluster.

enum cluster-getslotmigrations-operationsince 0.3.0-dev

Which way a slot migration moves the slots.

  • import

    IMPORT: to this node.

  • export

    EXPORT: from this node.

record cluster-getslotmigrations-entrysince 0.3.0-dev

A slot migration, see cluster-getslotmigrations.

  • link-name: string

    The ID of the migration.

  • operation: cluster-getslotmigrations-operation
  • slot-ranges: list<tuple<u16, u16>>

    The ranges of slots, start and end both included.

  • target-node: string

    The ID of the node the slots move to.

  • source-node: string

    The ID of the node the slots move from.

  • create-time: unix-time-seconds
  • last-update-time: unix-time-seconds
  • last-ack-time: unix-time-seconds
  • state: string

    The state of the migration, for people to read.

  • message: string

    More details of the state, for people to read.

  • cow-size: integer

    The bytes copied on write while forked for the migration.

record cluster-migrateslots-groupsince 0.3.0-dev

Ranges of slots to migrate to a node, see cluster-migrateslots.

  • ranges: list<tuple<u16, u16>>

    The ranges of slots, start and end both included.

  • node-id: string

    The ID of the node to migrate the slots to.

  • auth: option<tuple<string, string>>

    AUTH username password: the credentials for the node, since Valkey 9.2.

enum cluster-reset-modesince 0.3.0-dev

How CLUSTER RESET resets a node.

  • hard

    HARD: also generates a new node ID and resets the epochs.

  • soft

    SOFT: the default.

variant cluster-setslot-statesince 0.3.0-dev

The state to set a slot to, see cluster-setslot.

  • importing: string

    IMPORTING node-id: importing the slot from the node.

  • migrating: string

    MIGRATING node-id: migrating the slot to the node.

  • node: string

    NODE node-id: assigned to the node.

  • stable

    STABLE: neither importing nor migrating.

enum commandlog-typesince 0.3.0-dev

A command log, see commandlog-get.

  • slow

    slow: commands that took longer than commandlog-execution-slower-than.

  • large-request

    large-request: commands larger than commandlog-request-larger-than.

  • large-reply

    large-reply: replies larger than commandlog-reply-larger-than.

record commandlog-entrysince 0.3.0-dev

An entry of the slow log or a command log.

  • id: integer

    The ID of the entry, unique until the server restarts.

  • timestamp: unix-time-seconds

    When the command ran.

  • value: integer

    The microseconds the command took, or for the large logs, the bytes of the request or reply.

  • arguments: list<string>

    The command and its arguments, long ones shortened.

  • client-address: string

    The client's address, ip:port.

  • client-name: string

    The client's name, see CLIENT SETNAME, empty when it has none.

type slowlog-entrysince 0.3.0-dev

An entry of the slow log, see slowlog-get.

record failover-targetsince 0.3.0-dev

Where FAILOVER fails over to.

  • host: string
  • port: u16
  • force: bool

    FORCE: fails over at the timeout, even before the replica has caught up.

record latency-histogram-entrysince 0.3.0-dev

The latency histogram of a command, see latency-histogram.

  • calls: integer

    The number of times the command ran.

  • histogram-usec: list<tuple<integer, integer>>

    The cumulative counts of the calls that took up to each number of microseconds, a power of 2.

record latency-latest-entrysince 0.3.0-dev

The latest sample of the latency of an event, see latency-latest.

record module-list-entrysince 0.3.0-dev

A loaded module, see module-list.

  • name: string
  • ver: integer

    The module's version.

  • path: string

    The path the module was loaded from.

  • args: list<string>

    The arguments the module was loaded with.

record role-primary-replicasince 0.3.0-dev

A replica of a primary, see role.

  • ip: string
  • port: u16
  • offset: integer

    The replication offset the replica last acknowledged.

record role-primarysince 0.3.0-dev

The replication state of a primary, see role.

record role-replicasince 0.3.0-dev

The replication state of a replica, see role.

  • primary-host: string
  • primary-port: u16
  • state: string

    The state of replication, e.g. connected, connecting or sync.

  • offset: integer

    The replication offset of the data received from the primary, -1 when not connected.

variant role-replysince 0.3.0-dev

The server's role in replication, see role.

  • primary: role-primary

    master

  • replica: role-replica

    slave

  • sentinel: list<string>

    sentinel: the names of the primaries it monitors.

flags shutdown-flagssince 0.3.0-dev

The modifiers of SHUTDOWN.

  • now

    NOW: does not wait for lagging replicas.

  • force

    FORCE: ignores errors that would prevent the shutdown, e.g. failing to save.

  • safe

    SAFE: refuses to shut down while it would lose the cluster's quorum of primaries.

  • failover

    FAILOVER: fails over to a replica first.

enum shutdown-savesince 0.3.0-dev

Whether SHUTDOWN saves to disk.

  • nosave

    NOSAVE: does not save, even with save points configured.

  • save

    SAVE: saves, even without save points configured.

variant acl-key-rulesince 0.3.0-dev

A rule for the keys a user may access.

  • add: string

    ~<pattern>: allows reading and writing the keys matching the glob-style pattern.

  • add-read: string

    %R~<pattern>: allows reading the keys matching the glob-style pattern.

  • add-write: string

    %W~<pattern>: allows writing the keys matching the glob-style pattern.

  • add-read-write: string

    %RW~<pattern>: allows reading and writing the keys matching the glob-style pattern, the same as add.

  • all

    allkeys: allows access to all keys, an alias for ~*.

  • reset

    resetkeys: removes all the allowed key patterns.

variant acl-channel-rulesince 0.3.0-dev

A rule for the Pub/Sub channels a user may access.

  • add: string

    &<pattern>: allows access to the Pub/Sub channels matching the glob-style pattern.

  • all

    allchannels: allows access to all Pub/Sub channels, an alias for &*.

  • reset

    resetchannels: removes all the allowed channel patterns, disconnecting the user's Pub/Sub clients that can no longer access their channels.

variant acl-command-rulesince 0.3.0-dev

A rule for the commands a user may call.

  • add: string

    +<command>: allows the command, or a subcommand, e.g. config|get.

  • add-category: string

    +@<category>: allows all the commands in the category, e.g. read, see ACL CAT for the categories.

  • add-first-arg: tuple<string, string>

    +<command>|<first-arg>: allows the command only with the given first argument, e.g. select with 0.

  • all

    allcommands: allows all commands, including those of modules loaded later, an alias for +@all.

  • remove: string

    -<command>: disallows the command, or a subcommand.

  • remove-category: string

    -@<category>: disallows all the commands in the category.

  • reset

    nocommands: disallows all commands, an alias for -@all.

variant acl-db-rulesince 0.3.0-dev

A rule for the databases a user may access.

  • db: list<u8>

    db=<id>[,<id>...]: allows access to the databases with the given IDs.

  • all

    alldbs: allows access to all databases.

  • reset

    resetdbs: removes all the allowed databases.

variant acl-selector-rulesince 0.3.0-dev

A rule of a selector, a set of permissions matched independently of the user's root permissions, the user may run a command when either permits it.

  • keys: acl-key-rule

    The keys the selector permits access to.

  • channel: acl-channel-rule

    The Pub/Sub channels the selector permits access to.

  • command: acl-command-rule

    The commands the selector permits.

  • db: acl-db-rule

    The databases the selector permits access to.

  • other: string

    A rule this interface does not know, e.g. from a newer server, sent as is.

variant acl-user-rulesince 0.3.0-dev

A rule for the user itself.

  • on

    on: enables the user, it is possible to authenticate as this user.

  • off

    off: disables the user, it is no longer possible to authenticate as this user, connections already authenticated keep working.

  • nopass

    nopass: removes all the user's passwords, any password then authenticates as the user.

  • sanitize-payload

    sanitize-payload: validates the payloads of the user's RESTORE commands, the default.

  • skip-sanitize-payload

    skip-sanitize-payload: skips validating the payloads of the user's RESTORE commands.

  • password: string

    ><password>: adds the password to the user's passwords.

  • hashed-password: string

    #<hash>: adds a password, by its SHA-256 hash as 64 lowercase hex characters, to the user's passwords.

  • remove-password: string

    <<password>: removes the password from the user's passwords.

  • remove-hashed-password: string

    !<hash>: removes a password, by its SHA-256 hash, from the user's passwords.

  • selector: list<acl-selector-rule>

    (<rule> ...): adds a selector, with the given rules.

  • clearselectors

    clearselectors: removes all the user's selectors.

  • reset

    reset: resets the user to its state when created, disabled, without passwords, keys, channels, commands or selectors.

variant acl-rulesince 0.3.0-dev

A rule of an ACL user, see acl-setuser.

https://valkey.io/topics/acl/

  • keys: acl-key-rule

    The keys the user may access.

  • channel: acl-channel-rule

    The Pub/Sub channels the user may access.

  • command: acl-command-rule

    The commands the user may call.

  • db: acl-db-rule

    The databases the user may access.

  • user: acl-user-rule

    The user itself, e.g. whether it is enabled and its passwords.

  • other: string

    A rule this interface does not know, e.g. from a newer server, sent as is.

record acl-list-entrysince 0.3.0-dev

A user and its rules, see acl-list.

  • username: string
  • rules: list<acl-rule>

    The user's rules, as the server normalized them, e.g. allkeys is ~*. Applied with acl-setuser, after reset, they recreate the user.

variant bit-rangesince 0.3.0-dev

bitmap commands A range of a string, negative from the end, for BITCOUNT and BITPOS.

  • from: integer

    start: the bytes from the start to the end of the string.

  • bytes: tuple<integer, integer>

    start end: the bytes from the start to the end, both included.

  • bits: tuple<integer, integer>

    start end BIT: the bits from the start to the end, both included.

variant bitfield-encodingsince 0.3.0-dev

The type of an integer field of a string, for BITFIELD.

  • signed: u8

    i1 to i64: a signed integer of the width in bits.

  • unsigned: u8

    u1 to u63: an unsigned integer of the width in bits.

variant bitfield-offsetsince 0.3.0-dev

Where an integer field of a string starts, for BITFIELD.

  • bit: u64

    The offset in bits.

  • field: u64

    #field: the field of the encoding's width, the offset in bits is the field times the width.

enum bitfield-overflowsince 0.3.0-dev

What a write does when the field overflows, OVERFLOW.

  • wrap

    WRAP: wraps around, the default.

  • sat

    SAT: saturates at the minimum or maximum.

  • fail

    FAIL: does not write, the result is none.

record bitfield-getsince 0.3.0-dev

GET encoding offset: the value of the field.

type bitfield-ro-getsince 0.3.0-dev

A GET operation, see bitfield-ro.

record bitfield-setsince 0.3.0-dev

SET encoding offset value: sets the field, the result is its previous value.

record bitfield-incrbysince 0.3.0-dev

INCRBY encoding offset increment: increments the field, the result is its new value.

variant bitfield-operationsince 0.3.0-dev

An operation of BITFIELD.

A write is preceded by an optional overflow mode, OVERFLOW WRAP | SAT | FAIL, for it and the following writes. None keeps the current mode, WRAP at the start of the command.

variant bitop-operationsince 0.3.0-dev

A bitwise operation of BITOP, and its source keys.

  • and: list<string>

    AND

  • or: list<string>

    OR

  • xor: list<string>

    XOR

  • not: string

    NOT: of a single key.

record command-key-spec-keywordsince 0.3.0-dev

The keyword before the first key, see command-key-spec-begin-search.

  • keyword: string
  • startfrom: integer

    The index of the argument to start searching from, from the end when negative.

record command-key-spec-rangesince 0.3.0-dev

A range of keys, see command-key-spec-find-keys.

  • lastkey: integer

    The index of the last key, relative to the first, from the end when negative.

  • keystep: integer

    The number of arguments from one key to the next.

  • limit: integer

    With a lastkey of -1, divides the remaining arguments, e.g. 2 for half of them.

record command-key-spec-keynumsince 0.3.0-dev

A number of keys, see command-key-spec-find-keys.

  • keynumidx: integer

    The index of the argument with the number of keys, relative to the first.

  • firstkey: integer

    The index of the first key, relative to the first.

  • keystep: integer

    The number of arguments from one key to the next.

variant command-key-spec-find-keyssince 0.3.0-dev

How a key spec finds the keys after the first one, see command-key-spec.

record command-key-specsince 0.3.0-dev

Where a command's keys are and how it uses them.

record command-info-replysince 0.3.0-dev

A command, see command and command-info.

  • name: string

    The command's name, e.g. get, or for a subcommand, config|get.

  • arity: integer

    The number of arguments, the name included, the minimum when negative.

  • flags: list<string>

    The command's flags, e.g. readonly and fast.

  • first-key: integer

    The index of the first key, 0 for none.

  • last-key: integer

    The index of the last key, from the end when negative.

  • step: integer

    The number of arguments from one key to the next.

  • acl-categories: list<string>

    The ACL categories of the command, e.g. @read.

  • tips: list<string>

    Hints for clients, e.g. nondeterministic_output.

  • key-specs: list<command-key-spec>

type command-replysince 0.3.0-dev

The details of a command, see command.

variant command-docs-argument-typesince 0.3.0-dev

The type of an argument of a command, see command-docs-argument.

  • string

    string

  • integer

    integer

  • double

    double

  • key

    key: a key, see key-spec-index.

  • pattern

    pattern: a glob-style pattern.

  • unix-time

    unix-time

  • pure-token

    pure-token: the token alone, without a value.

  • oneof

    oneof: one of the arguments it contains.

  • block

    block: the arguments it contains, together.

  • other: string

    A type this interface does not know, e.g. from a newer server.

record command-docs-argumentsince 0.3.0-dev

An argument of a command, see command-docs.

  • parent: option<u32>

    The index of the oneof or block argument containing this one, in the command's arguments, none at the top level.

  • name: string
  • type: command-docs-argument-type
  • display-text: option<string>

    The name to show for the argument.

  • key-spec-index: option<integer>

    The index of the argument's key spec, for a key.

  • token: option<string>

    The token before the argument's value, e.g. EX, or for a pure-token, the token alone.

  • summary: option<string>
  • since: option<string>

    The version that added the argument.

  • deprecated-since: option<string>
  • flags: list<string>

    The argument's flags, e.g. optional, multiple and multiple_token.

record command-docs-replysince 0.3.0-dev

The documentation of a command, see command-docs.

  • name: string

    The command's name, e.g. get, or for a subcommand, config|get.

  • summary: string
  • since: string

    The version that added the command.

  • group: string

    The command's group, e.g. string.

  • complexity: option<string>

    The command's time complexity, none for a few commands, e.g. MONITOR.

  • module: option<string>

    The module of the command, for a module's command.

  • doc-flags: list<string>

    The command's documentation flags, e.g. deprecated or syscmd.

  • deprecated-since: option<string>
  • replaced-by: option<string>

    The command to use instead, for a deprecated command.

  • history: list<tuple<string, string>>

    The changes to the command, the version of each and what changed.

  • arguments: list<command-docs-argument>

    The arguments, depth first, those an argument contains after it.

variant client-setinfo-attrsince 0.3.0-dev

Information about the library of a connection, see client-setinfo.

  • lib-name: string

    LIB-NAME: the name of the library, e.g. valkey-wasm.

  • lib-ver: string

    LIB-VER: the version of the library.

enum client-tracking-modesince 0.3.0-dev

Which keys tracking tracks without CLIENT CACHING.

  • optin

    OPTIN: none, only those of commands after CLIENT CACHING YES.

  • optout

    OPTOUT: all, except those of commands after CLIENT CACHING NO.

record client-tracking-optionssince 0.3.0-dev

The options of CLIENT TRACKING ON.

  • prefixes: option<list<string>>

    PREFIX prefix: with bcast, only notifies about keys with the prefixes.

  • bcast: bool

    BCAST: notifies about every change of the keys with the prefixes, read or not.

  • mode: option<client-tracking-mode>
  • noloop: bool

    NOLOOP: does not notify about the keys the connection changed itself.

variant client-trackinginfo-redirectsince 0.3.0-dev

Where a connection's tracking notifications are redirected, see client-trackinginfo.

Redirecting is for RESP2, which the connection does not use, but CLIENT TRACKING REDIRECT may still be sent with connection.exchange.

  • not-tracking

    -1: tracking is not on.

  • not-redirected

    0: tracking is on, the notifications are not redirected.

  • redirected: integer

    The ID of the connection the notifications are redirected to.

record client-trackinginfo-replysince 0.3.0-dev

A connection's tracking state, see client-trackinginfo.

  • flags: list<string>

    The tracking flags, e.g. on, bcast, optin or noloop.

  • redirect: client-trackinginfo-redirect

    Where the notifications are redirected.

  • prefixes: list<string>

    The prefixes of BCAST.

variant command-list-filtersince 0.3.0-dev

The filter of COMMAND LIST.

  • module: string

    MODULE module-name: the commands of the module.

  • aclcat: string

    ACLCAT category: the commands in the ACL category.

  • pattern: string

    PATTERN pattern: the commands matching the glob-style pattern.

record geo-coordinatessince 0.3.0-dev

geo commands A position on the Earth.

The exact limits, as specified by EPSG:900913 / EPSG:3785 / OSGEO:41001

  • longitude: double

    The longitude, from -180 to 180 degrees.

  • latitude: double

    The latitude, from -85.05112878 to 85.05112878 degrees.

enum geo-unitsince 0.3.0-dev

A unit of distance.

  • m

    m: meters.

  • km

    km: kilometers.

  • ft

    ft: feet.

  • mi

    mi: miles.

enum geoadd-conditionsince 0.3.0-dev

Only add or only update members, GEOADD's NX and XX.

  • nx

    Only add new members, never update existing ones.

  • xx

    Only update existing members, never add new ones.

variant geosearch-fromsince 0.3.0-dev

The center of a search, FROMMEMBER or FROMLONLAT.

record geosearch-radiussince 0.3.0-dev

BYRADIUS: a circle around the center.

record geosearch-boxsince 0.3.0-dev

BYBOX: a rectangle around the center.

variant geosearch-shapesince 0.3.0-dev

The area of a search.

  • radius: geosearch-radius

    [ FROMMEMBER member | FROMLONLAT longitude latitude ] BYRADIUS radius unit

  • box: geosearch-box

    [ FROMMEMBER member | FROMLONLAT longitude latitude ] BYBOX width height unit

  • polygon: list<geo-coordinates>

    BYPOLYGON num-vertices longitude latitude [ longitude latitude ... ]: the polygon with the vertices, in order, which has no center.

type geosearchstore-shapesince 0.3.0-dev

The area to search, see geosearchstore.

record geosearch-countsince 0.3.0-dev

At most a count of the members, COUNT count [ ANY ].

  • count: integer
  • any: bool

    ANY: returns as soon as enough members are found, rather than the nearest ones.

type geosearchstore-countsince 0.3.0-dev

The number of members to store, see geosearchstore.

flags geosearch-with-flagssince 0.3.0-dev

The details GEOSEARCH returns of each member it found.

  • withcoord

    WITHCOORD: the position.

  • withdist

    WITHDIST: the distance from the center.

  • withhash

    WITHHASH: the geohash, as an integer.

record geosearch-with-resultsince 0.3.0-dev

A member a search found, with the details asked for.

  • member: string-or-bytes
  • distance: option<double>

    WITHDIST: the distance from the center, in the unit of the shape.

  • hash: option<integer>

    WITHHASH: the geohash, as an integer.

  • coordinates: option<geo-coordinates>

    WITHCOORD: the position.

enum hpersist-resultsince 0.3.0-dev

hash commands The outcome of removing the expiration of a hash field.

  • does-not-exist

    -2: the field does not exist, or the hash does not exist.

  • no-expiration

    -1: the field exists, but has no expiration.

  • removed

    1: the expiration was removed.

enum hsetex-conditionsince 0.3.0-dev

Only set the fields when the hash does, or does not, exist, HSETEX's NX and XX.

  • nx

    Only set the fields when the hash does not exist.

  • xx

    Only set the fields when the hash exists.

enum hsetex-field-conditionsince 0.3.0-dev

Only set the fields when none, or all, of them exist, HSETEX's FNX and FXX.

  • fnx

    Only set the fields when none of them exist.

  • fxx

    Only set the fields when all of them exist.

enum hexpire-resultsince 0.3.0-dev

The outcome of setting the expiration of a hash field, e.g. with HEXPIRE.

  • does-not-exist

    -2: key does not exist, or field does not exist in the HASH.

  • condition-not-met

    0: the specified NX | XX | GT | LT condition has not been met.

  • applied

    1: the expiration time was applied.

  • zero-seconds

    2: when called with 0 seconds.

type hexpireat-resultsince 0.3.0-dev

The result for a field, see hexpireat.

type hpexpire-resultsince 0.3.0-dev

The result for a field, see hpexpire.

type hpexpireat-resultsince 0.3.0-dev

The result for a field, see hpexpireat.

variant restore-ttlsince 0.3.0-dev

keyspace commands The expiration of a key restore creates.

variant key-typesince 0.3.0-dev

The type of the value stored at a key.

  • string

    string

  • list

    list

  • set

    set

  • zset

    zset: a sorted set.

  • hash

    hash

  • stream

    stream

  • other: string

    The type of a module, by name.

flags migrate-flagssince 0.3.0-dev

The options of MIGRATE.

  • copy

    COPY: keeps the keys in this instance.

  • replace

    REPLACE: replaces keys that exist in the other instance.

variant migrate-authsince 0.3.0-dev

The credentials to authenticate to the other instance with, for MIGRATE.

  • password: string

    AUTH password

  • username-password: tuple<string, string>

    AUTH2 username password

record sort-optssince 0.3.0-dev

How SORT orders and projects the elements of a list, set or sorted set.

  • by: option<string>

    BY pattern: sorts by the values of the keys the pattern names, * replaced with each element, or nosort to skip sorting.

  • limit: option<limit>

    LIMIT offset count: a range of the sorted elements.

  • get: option<list<string>>

    GET pattern: returns the values of the keys each pattern names instead of the elements, # for the element itself.

  • order: option<sort-order>

    order to sort elements.

  • alpha: bool

    ALPHA: sorts lexicographically, rather than numerically.

type sort-ro-optssince 0.3.0-dev

The options of the sort, see sort-ro.

enum list-sidesince 0.3.0-dev

list commands An end of a list.

  • left

    LEFT: the head, the first element.

  • right

    RIGHT: the tail, the last element.

enum linsert-positionsince 0.3.0-dev

Where LINSERT inserts an element, relative to the pivot.

  • before

    BEFORE: in front of the pivot.

  • after

    AFTER: behind the pivot.

variant linsert-resultsince 0.3.0-dev

The outcome of LINSERT.

  • inserted: integer

    The element was inserted, the length of the list after it.

  • no-such-key

    0: the key does not exist, nothing was inserted.

  • pivot-not-found

    -1: the pivot is not in the list, nothing was inserted.

enum function-restore-policysince 0.3.0-dev

scripting commands What function-restore does with the libraries already loaded.

  • flush

    FLUSH: deletes them first.

  • append

    APPEND: keeps them, failing when a library of the same name is loaded.

  • replace

    REPLACE: keeps them, replacing those with a library of the same name.

enum flush-modesince 0.3.0-dev

Whether a flush happens in the background, ASYNC, or before replying, SYNC.

  • async

    ASYNC

  • sync

    SYNC

record function-list-functionsince 0.3.0-dev

A function of a library.

  • name: string
  • description: option<string>
  • flags: list<string>

    The function's flags, e.g. no-writes.

record function-list-librarysince 0.3.0-dev

A library of functions.

  • library-name: string
  • engine: string

    The engine that runs the library, e.g. LUA.

  • functions: list<function-list-function>
  • library-code: option<string>

    The library's source code, with withcode.

record function-stats-runningsince 0.3.0-dev

The function that is running.

  • name: string
  • command: list<string>

    The command and its arguments that called the function.

  • duration: duration-milliseconds

    How long the function has been running.

record function-stats-enginesince 0.3.0-dev

The libraries and functions of an engine.

record function-stats-replysince 0.3.0-dev

The function that is running, and the libraries and functions of each engine.

variant score-boundsince 0.3.0-dev

sortedset commands A bound of a range of scores.

  • inclusive: double

    The score, included in the range.

  • exclusive: double

    (score: the score, excluded from the range.

  • unbounded

    -inf as the min, +inf as the max, the start is the max with REV.

variant lex-boundsince 0.3.0-dev

A bound of a range of members, for members of equal score, ordered lexicographically.

  • inclusive: string-or-bytes

    [member: the member, included in the range.

  • exclusive: string-or-bytes

    (member: the member, excluded from the range.

  • unbounded

    - as the min, + as the max, the start is the max with REV.

enum zmpop-endsince 0.3.0-dev

Which end of a sorted set to pop from.

  • min

    The members with the lowest scores.

  • max

    The members with the highest scores.

type bzmpop-endsince 0.3.0-dev

The end to pop from, see bzmpop.

enum zset-aggregatesince 0.3.0-dev

How scores combine for a member in several sorted sets.

  • sum

    The sum of the weighted scores, the default.

  • min

    The lowest weighted score.

  • max

    The highest weighted score.

variant zrange-bysince 0.3.0-dev

The range of ZRANGE and ZRANGESTORE, start and stop, given as they are sent: with REV, the higher bound first.

type zrangestore-bysince 0.3.0-dev

The range of members to store, see zrangestore.

variant zrange-withscores-bysince 0.3.0-dev

The range of ZRANGE WITHSCORES, which does not support BYLEX, see zrange-by.

enum zadd-conditionsince 0.3.0-dev

Only update or only add members, ZADD's NX and XX.

  • nx

    Only add new members, never update existing ones.

  • xx

    Only update existing members, never add new ones.

enum zadd-comparisonsince 0.3.0-dev

Only update a member's score when the new score is greater or less, ZADD's GT and LT.

  • gt

    Only update when the new score is greater than the current one.

  • lt

    Only update when the new score is less than the current one.

type stream-idsince 0.3.0-dev

stream commands The ID of a stream entry, <milliseconds-time>-<sequence-number>, e.g. 1526919030474-55.

Commands that add an entry also accept *, for the server to generate the ID.

  • string

enum stream-trim-efficiencysince 0.3.0-dev

How exactly a stream is trimmed. Nearly exact trimming is more efficient, the stream may keep a few entries more than the threshold.

  • exact

    =: exact trimming

  • mearly-exact

    ~: nearly exact trimming

record stream-trim-maxlensince 0.3.0-dev

Trims the stream to a maximum length, MAXLEN [ = | ~ ] threshold [ LIMIT count ].

  • efficiency: option<stream-trim-efficiency>

    Exact, =, when none.

  • threshold: integer

    The maximum number of entries kept.

  • limit: option<integer>

    The maximum number of entries evicted, only with nearly exact trimming, 0 for no limit.

record stream-trim-minidsince 0.3.0-dev

Trims the entries with lower IDs, MINID [ = | ~ ] threshold [ LIMIT count ].

  • efficiency: option<stream-trim-efficiency>

    Exact, =, when none.

  • threshold: stream-id

    The lowest ID kept.

  • limit: option<integer>

    The maximum number of entries evicted, only with nearly exact trimming, 0 for no limit.

variant stream-trimsince 0.3.0-dev

How a stream is trimmed, e.g. with XADD or XTRIM.

  • maxlen: stream-trim-maxlen

    Evicts entries as long as the stream's length exceeds the specified threshold, where threshold is a positive integer.

  • minid: stream-trim-minid

    Evicts entries with IDs lower than threshold, where threshold is a stream ID.

record xclaim-optssince 0.3.0-dev

Options of XCLAIM.

  • idle: option<duration-milliseconds>

    IDLE ms: sets the idle time of the entries, the time since they were last delivered, instead of resetting it.

  • time: option<unix-time-milliseconds>

    TIME unix-time-milliseconds: sets the idle time of the entries to the time since this instant.

  • retrycount: option<integer>

    RETRYCOUNT count: sets the delivery count of the entries, instead of incrementing it.

  • force: bool

    FORCE: claims the entries even when they are not pending for any consumer, as long as they exist in the stream.

  • lastid: option<stream-id>

    LASTID lastid: sets the ID of the last entry delivered to the group.

record xinfo-consumers-entrysince 0.3.0-dev

A consumer of a group, see xinfo-consumers.

  • name: string

    The consumer's name.

  • pending: integer

    The number of entries pending for the consumer.

  • idle: duration-milliseconds

    The time since the consumer last attempted an interaction, e.g. XREADGROUP, XCLAIM or XAUTOCLAIM.

  • inactive: option<duration-milliseconds>

    The time since the consumer last interacted successfully, e.g. read or claimed entries. None when the consumer has never been active.

record xinfo-groups-entrysince 0.3.0-dev

A consumer group of a stream, see xinfo-groups.

  • name: string

    The group's name.

  • consumers: integer

    The number of consumers in the group.

  • pending: integer

    The number of entries in the group's pending entries list (PEL), delivered but not acknowledged.

  • last-delivered-id: stream-id

    The ID of the last entry delivered to the group's consumers.

  • entries-read: option<integer>

    The logical read counter of the last entry delivered to the group's consumers, none when unknown.

  • lag: option<integer>

    The number of entries in the stream not yet delivered to the group's consumers, none when it cannot be determined.

record xinfo-stream-replysince 0.3.0-dev

Information about a stream, see xinfo-stream.

  • length: integer

    The number of entries in the stream.

  • radix-tree-keys: integer

    The number of keys in the radix tree storing the stream.

  • radix-tree-nodes: integer

    The number of nodes in the radix tree storing the stream.

  • groups: integer

    The number of consumer groups of the stream.

  • last-generated-id: option<stream-id>

    The ID of the last entry added to the stream, none when no entry was ever added.

  • max-deleted-entry-id: option<stream-id>

    The highest ID deleted from the stream, none when no entry was ever deleted.

  • entries-added: integer

    The number of entries added to the stream over its lifetime.

  • first-entry: option<tuple<stream-id, map<string, string-or-bytes>>>

    The ID and fields of the first entry. None when the stream is empty.

  • last-entry: option<tuple<stream-id, map<string, string-or-bytes>>>

    The ID and fields of the last entry. None when the stream is empty.

record xinfo-stream-reply-full-consumersince 0.3.0-dev

A consumer of a group, with its pending entries.

  • name: string

    The consumer's name.

  • seen-time: unix-time-milliseconds

    When the consumer last attempted an interaction, e.g. XREADGROUP, XCLAIM or XAUTOCLAIM.

  • active-time: option<unix-time-milliseconds>

    When the consumer last interacted successfully, e.g. read or claimed entries. None when the consumer has never been active.

  • pel-count: integer

    The number of entries pending for the consumer, delivered but not acknowledged.

  • pending: list<tuple<stream-id, unix-time-milliseconds, integer>>

    The consumer's pending entries, the ID of each, when it was last delivered and the number of times it was delivered.

record xinfo-stream-reply-full-groupsince 0.3.0-dev

A consumer group of a stream, with its pending entries and consumers.

  • name: string

    The group's name.

  • last-delivered-id: stream-id

    The ID of the last entry delivered to the group's consumers.

  • entries-read: option<integer>

    The logical read counter of the last entry delivered to the group's consumers, none when unknown.

  • lag: option<integer>

    The number of entries in the stream not yet delivered to the group's consumers, none when it cannot be determined.

  • pel-count: integer

    The number of entries in the group's pending entries list (PEL), delivered but not acknowledged.

  • pending: list<tuple<stream-id, string, unix-time-milliseconds, integer>>

    The group's pending entries, the ID of each, the consumer it was delivered to, when it was last delivered and the number of times it was delivered.

  • consumers: list<xinfo-stream-reply-full-consumer>

    The group's consumers.

record xinfo-stream-reply-fullsince 0.3.0-dev

Information about a stream, its entries and consumer groups, see xinfo-stream-full.

  • length: integer

    The number of entries in the stream.

  • radix-tree-keys: integer

    The number of keys in the radix tree storing the stream.

  • radix-tree-nodes: integer

    The number of nodes in the radix tree storing the stream.

  • last-generated-id: option<stream-id>

    The ID of the last entry added to the stream, none when no entry was ever added.

  • max-deleted-entry-id: option<stream-id>

    The highest ID deleted from the stream, none when no entry was ever deleted.

  • entries-added: integer

    The number of entries added to the stream over its lifetime.

  • entries: list<tuple<stream-id, map<string, string-or-bytes>>>

    The ID and fields of the entries, in ascending ID order, up to the count given.

  • groups: list<xinfo-stream-reply-full-group>

    The consumer groups of the stream.

record xpending-summarysince 0.3.0-dev

The pending entries of a consumer group, see xpending.

  • count: integer

    The number of pending entries.

  • lowest-id: option<stream-id>

    The lowest ID of the pending entries, none when there are none.

  • highest-id: option<stream-id>

    The highest ID of the pending entries, none when there are none.

  • consumers: list<tuple<string, integer>>

    Each consumer with pending entries, and how many it has.

record xpending-extended-entrysince 0.3.0-dev

The pending entries of a consumer group, see xpending-extended.

  • id: stream-id

    The ID of the message.

  • name: string

    The name of the consumer that fetched the message and has still to acknowledge it. We call it the current owner of the message.

  • since-delivery: duration-milliseconds

    The number of milliseconds that elapsed since the last time this message was delivered to this consumer.

  • delivery-count: integer

    The number of times this message was delivered.

variant getex-ttlsince 0.3.0-dev

string commands The expiration to set on a key, see getex.

  • ex: duration-seconds

    Set the specified expire time, in seconds.

  • px: duration-milliseconds

    Set the specified expire time, in milliseconds.

  • exat: unix-time-seconds

    Set the specified Unix time at which the key will expire, in seconds.

  • pxat: unix-time-milliseconds

    Set the specified Unix time at which the key will expire, in milliseconds.

  • persist

    Remove the time to live associated with the key.

type hgetex-ttlsince 0.3.0-dev

The expiration to set on the fields, see hgetex.

record lcs-idx-matchsince 0.3.0-dev

A part of the longest common subsequence.

  • key1-range: tuple<integer, integer>

    The inclusive start and end positions of the match in the first key's string.

  • key2-range: tuple<integer, integer>

    The inclusive start and end positions of the match in the second key's string.

  • len: option<integer>

    The length of the match, with with-match-len.

record lcs-idx-replysince 0.3.0-dev

The longest common subsequence of two strings, as the ranges matching in each, see lcs-idx.

  • matches: list<lcs-idx-match>

    The ranges that match, from the end of the strings to their start.

  • len: integer

    The length of the longest common subsequence.

variant msetex-preconditionsince 0.3.0-dev

The condition for setting the keys, see msetex.

  • nx

    Only set the keys if all of them do not already exist.

  • xx

    Only set the keys if all of them already exist.

variant set-preconditionsince 0.3.0-dev

The condition for setting a key, see set.

  • nx

    Only set the key if it does not already exist.

  • xx

    Only set the key if it already exists.

  • ifeq: string-or-bytes

    Set the key if the comparison value matches the existing value.

  • ifne: string-or-bytes

    Set the key if the comparison value does not match the existing value.

variant set-ttlsince 0.3.0-dev

The expiration to set on a key, see set.

  • ex: duration-seconds

    Set the specified expire time, in seconds.

  • px: duration-milliseconds

    Set the specified expire time, in milliseconds.

  • exat: unix-time-seconds

    Set the specified Unix time at which the key will expire, in seconds.

  • pxat: unix-time-milliseconds

    Set the specified Unix time at which the key will expire, in milliseconds.

  • keepttl

    Retain the time to live associated with the keys.

type msetex-ttlsince 0.3.0-dev

The expiration to set on the keys, see msetex.

type hsetex-ttlsince 0.3.0-dev

The expiration to set on the fields, see hsetex.

WIT

/// The types of the package's interfaces, their stable public names.
///
/// The other interfaces use these types under names of their own, which may change, e.g. renamed
/// to avoid clashing with a function for a new command. Refer to a type through this interface for
/// a name that does not change.
interface types {
  /// resp
  /// An encoding error, converting RESP values to or from bytes.
  @since(version = 0.3.0-dev)
  type resp-error = string;

  @since(version = 0.3.0-dev)
  type integer = s64;

  @since(version = 0.3.0-dev)
  type double = f64;

  /// Raw bytes, e.g. a bulk string, which Valkey keeps as given, UTF-8 or not.
  @since(version = 0.3.0-dev)
  type bytes = list<u8>;

  @since(version = 0.3.0-dev)
  variant string-or-bytes {
    /// utf-8 decoded bytes.
    %string(string),
    /// bytes that cannot be represented as a utf-8 string.
    bytes(bytes),
  }

  /// Values nested within an aggregate type. Since WIT types are not allowed to depend on
  /// themselves, nested values are stored as encoded RESP.
  @since(version = 0.3.0-dev)
  type resp-nested-value = list<u8>;

  @since(version = 0.3.0-dev)
  variant resp-value {
    %string(string),
    error(string),
    integer(integer),
    bulk-string(bytes),
    array(list<resp-nested-value>),
    null,
    boolean(bool),
    double(double),
    big-number(string),
    bulk-error(bytes),
    verbatim-string(tuple<string, string>),
    %map(list<tuple<resp-nested-value, resp-nested-value>>),
    set(list<resp-nested-value>),
    push(list<resp-nested-value>),
  }

  /// connection
  /// The errors of a connection and of every command interface.
  @since(version = 0.3.0-dev)
  variant error-code {
    /// The transport closed while a reply was outstanding, or before the command was sent. Holds
    /// the transport's error when it did not close gracefully.
    closed(option<string>),
    /// Client errors are semantic issues with input/output values, e.g. a reply that does not
    /// have the shape the command expects.
    client(string),
    /// RESP errors are encoding issues converting values to/from bytes.
    resp(resp-error),
    /// Server errors are Error or BulkError RESP values returned directly from the server. An Error
    /// is a string, a BulkError a string when it is UTF-8, bytes otherwise.
    server(string-or-bytes),
    /// The reader of a stream fell too far behind and its stream was closed, rather than
    /// holding up the connection. What the stream missed is lost.
    lagged,
  }

  /// What a subscription is subscribed to, see `connection.subscription`.
  @since(version = 0.3.0-dev)
  variant subscription-target {
    /// A channel, see SUBSCRIBE.
    channel(string),
    /// A pattern of channels, see PSUBSCRIBE.
    pattern(string),
    /// A shard channel, see SSUBSCRIBE.
    shardchannel(string),
  }

  /// A message published to a channel.
  ///
  /// A subscription with overlapping targets, e.g. a channel and a pattern matching it, receives
  /// a message once for each target.
  @since(version = 0.3.0-dev)
  record subscription-message {
    /// The message as published, UTF-8 or not.
    payload: string-or-bytes,
    /// The channel the message was published to: a channel, published with PUBLISH, or a shard
    /// channel, published with SPUBLISH. Channels and shard channels are separate, a channel
    /// and a shard channel of the same name are not the same. `target` tells them apart, a
    /// `shardchannel` target for a shard channel, a `channel` or `pattern` target otherwise.
    channel: string,
    /// The subscription's target that matched the channel, the channel itself, or a pattern
    /// matching it.
    target: subscription-target,
  }

  /// Why a target is no longer subscribed to.
  @since(version = 0.3.0-dev)
  enum unsubscribe-reason {
    /// By the subscription, e.g. its `unsubscribe`.
    requested,
    /// By the server on its own, e.g. the slot of a shard channel moved to another node.
    by-server,
    /// By `connection.reset`.
    reset,
  }

  /// What a subscription's stream carries, in the order it happened.
  @since(version = 0.3.0-dev)
  variant subscription-event {
    /// The server confirmed the target, its messages may arrive from now on.
    subscribed(subscription-target),
    /// The target is no longer subscribed to, none of its messages arrive after this.
    unsubscribed(tuple<subscription-target, unsubscribe-reason>),
    message(subscription-message),
  }

  /// shared by the commands
  /// A duration in whole seconds, e.g. `EX seconds`.
  @since(version = 0.3.0-dev)
  record duration-seconds {
    ex: u64,
  }

  /// A duration in whole milliseconds, e.g. `PX milliseconds`.
  @since(version = 0.3.0-dev)
  record duration-milliseconds {
    px: u64,
  }

  /// Options for establishing a connection.
  @since(version = 0.3.0-dev)
  record connect-opts {
    /// The username and password to authenticate with.
    auth: option<tuple<string, string>>,
    /// The name of the connection, see `CLIENT SETNAME`.
    client-name: option<string>,
    /// Enables keep-alive pings at this interval, see `connection.set-keep-alive`.
    keep-alive-interval: option<duration-milliseconds>,
  }

  /// A point in time as whole seconds since the Unix epoch, e.g. `EXAT unix-time-seconds`.
  @since(version = 0.3.0-dev)
  record unix-time-seconds {
    exat: s64,
  }

  /// A point in time as whole milliseconds since the Unix epoch, e.g. `PXAT
  /// unix-time-milliseconds`.
  @since(version = 0.3.0-dev)
  record unix-time-milliseconds {
    pxat: s64,
  }

  /// Where an incremental iteration continues from, e.g. with HSCAN.
  ///
  /// A scan returns the cursor to resume from, always `resume`, none once the scan is complete.
  /// Pass it to the next call until then.
  @since(version = 0.3.0-dev)
  variant cursor {
    /// Starts a new scan, the cursor `0`.
    start,
    /// Continues a scan from the opaque cursor the previous call returned, `0` fails with a client
    /// error, use `start`.
    resume(string),
  }

  /// The condition for setting an expiration, e.g. with EXPIRE or HEXPIRE.
  @since(version = 0.3.0-dev)
  enum ttl-mode {
    /// Set expiration only when the field has no expiration.
    nx,
    /// Set expiration only when the field has an existing expiration.
    xx,
    /// Set expiration only when the new expiration is greater than current one.
    gt,
    /// Set expiration only when the new expiration is less than current one.
    lt,
  }

  /// The remaining time to live of a key or hash field, to the second, see `ttl` and `httl`.
  @since(version = 0.3.0-dev)
  variant ttl-reply {
    /// -2: the key does not exist, or for a hash field, the field or the hash does not exist.
    does-not-exist,
    /// -1: the key or field exists, but has no expiration.
    no-expiration,
    /// The time until it expires.
    expires-in(duration-seconds),
  }

  /// The remaining time to live of a field, see `httl`.
  @since(version = 0.3.0-dev)
  type httl-reply = ttl-reply;

  /// The remaining time to live of a key or hash field, to the millisecond, see `pttl` and `hpttl`.
  @since(version = 0.3.0-dev)
  variant pttl-reply {
    /// -2: the key does not exist, or for a hash field, the field or the hash does not exist.
    does-not-exist,
    /// -1: the key or field exists, but has no expiration.
    no-expiration,
    /// The time until it expires.
    expires-in(duration-milliseconds),
  }

  /// The remaining time to live of a field, see `hpttl`.
  @since(version = 0.3.0-dev)
  type hpttl-reply = pttl-reply;

  /// When a key or hash field expires, to the second, see `expiretime` and `hexpiretime`.
  @since(version = 0.3.0-dev)
  variant expiretime-reply {
    /// -2: the key does not exist, or for a hash field, the field or the hash does not exist.
    does-not-exist,
    /// -1: the key or field exists, but has no expiration.
    no-expiration,
    /// The time at which it expires.
    expires-at(unix-time-seconds),
  }

  /// The expiration time of a field, see `hexpiretime`.
  @since(version = 0.3.0-dev)
  type hexpiretime-reply = expiretime-reply;

  /// When a key or hash field expires, to the millisecond, see `pexpiretime` and `hpexpiretime`.
  @since(version = 0.3.0-dev)
  variant pexpiretime-reply {
    /// -2: the key does not exist, or for a hash field, the field or the hash does not exist.
    does-not-exist,
    /// -1: the key or field exists, but has no expiration.
    no-expiration,
    /// The time at which it expires.
    expires-at(unix-time-milliseconds),
  }

  /// The expiration time of a field, see `hpexpiretime`.
  @since(version = 0.3.0-dev)
  type hpexpiretime-reply = pexpiretime-reply;

  /// A range of a sorted result, `LIMIT offset count`.
  @since(version = 0.3.0-dev)
  record limit {
    /// The number of elements skipped.
    offset: integer,
    /// The maximum number of elements returned, negative for all of them.
    count: integer,
  }

  @since(version = 0.3.0-dev)
  enum sort-order {
    /// ascending, smallest to largest.
    asc,
    /// descending, largest to smallest.
    desc,
  }

  /// admin commands
  /// Whether a user may run a command, see `acl-dryrun`.
  @since(version = 0.3.0-dev)
  variant acl-dryrun-result {
    /// The user may run the command.
    allowed,
    /// The user may not run the command, and why.
    denied(string),
  }

  /// A security event, a command or authentication the rules denied, see `acl-log`.
  @since(version = 0.3.0-dev)
  record acl-log-entry {
    /// The number of events like this one, within 60 seconds of each other.
    count: integer,
    /// What was denied, e.g. `command`, `key`, `channel` or `auth`.
    reason: string,
    /// Where it was denied, e.g. `toplevel`, `multi` or `lua`.
    context: string,
    /// The command, key or channel that was denied.
    object: string,
    username: string,
    /// The seconds since the latest of these events.
    age-seconds: double,
    /// The connection, in the format of CLIENT LIST.
    client-info: string,
    /// The ID of the entry, since Valkey 7.2.
    entry-id: option<integer>,
    /// When the first of these events happened, since Valkey 7.2.
    timestamp-created: option<unix-time-milliseconds>,
    /// When the latest of these events happened, since Valkey 7.2.
    timestamp-last-updated: option<unix-time-milliseconds>,
  }

  /// What BGSAVE does.
  @since(version = 0.3.0-dev)
  enum bgsave-operation {
    /// `SCHEDULE`: saves once the rewrite of the append-only file in progress is done.
    schedule,
    /// `CANCEL`: cancels the save in progress, or scheduled.
    cancel,
  }

  /// The type of a connection, for the `client-filter`.
  @since(version = 0.3.0-dev)
  enum client-type {
    /// `normal`
    normal,
    /// `master`: the connection to the primary of a replica.
    primary,
    /// `replica`
    replica,
    /// `pubsub`
    pubsub,
  }

  /// A filter of connections, for CLIENT KILL and CLIENT LIST.
  @since(version = 0.3.0-dev)
  variant client-filter {
    /// `ID client-id [ client-id ... ]`
    id(list<integer>),
    /// `TYPE`
    %type(client-type),
    /// `USER username`
    user(string),
    /// `ADDR ip:port`: the address of the client.
    addr(string),
    /// `LADDR ip:port`: the address of the server the client connected to.
    laddr(string),
    /// `SKIPME YES | NO`: whether to skip this connection, yes by default for CLIENT KILL.
    skipme(bool),
    /// `MAXAGE`: connections older than the time.
    maxage(duration-seconds),
    /// `NAME`
    name(string),
    /// `IDLE`: connections idle for at least the time.
    idle(duration-seconds),
    /// `FLAGS`: connections with all the flags, e.g. `N`.
    %flags(string),
    /// `LIB-NAME`
    lib-name(string),
    /// `LIB-VER`
    lib-ver(string),
    /// `DB`
    db(integer),
    /// `CAPA`: connections with the capability, e.g. `redirect`.
    capa(string),
    /// `IP`
    ip(string),
    /// `NOT-ID client-id [ client-id ... ]`
    not-id(list<integer>),
    /// `NOT-TYPE`
    not-type(client-type),
    /// `NOT-USER`
    not-user(string),
    /// `NOT-ADDR`
    not-addr(string),
    /// `NOT-LADDR`
    not-laddr(string),
    /// `NOT-NAME`
    not-name(string),
    /// `NOT-FLAGS`
    not-flags(string),
    /// `NOT-LIB-NAME`
    not-lib-name(string),
    /// `NOT-LIB-VER`
    not-lib-ver(string),
    /// `NOT-DB`
    not-db(integer),
    /// `NOT-CAPA`
    not-capa(string),
    /// `NOT-IP`
    not-ip(string),
  }

  /// Which commands CLIENT PAUSE suspends.
  @since(version = 0.3.0-dev)
  enum client-pause-mode {
    /// `WRITE`: commands that may write.
    write,
    /// `ALL`: every command, the default.
    all,
  }

  /// How CLIENT UNBLOCK unblocks a connection.
  @since(version = 0.3.0-dev)
  enum client-unblock-type {
    /// `TIMEOUT`: as if the command timed out, the default.
    timeout,
    /// `ERROR`: with an `UNBLOCKED` error.
    error,
  }

  /// The outcome of CLUSTER BUMPEPOCH.
  @since(version = 0.3.0-dev)
  variant cluster-bumpepoch-result {
    /// `BUMPED`: the config epoch was advanced, to this one.
    bumped(integer),
    /// `STILL`: the config epoch is already the greatest in the cluster, this one.
    still(integer),
  }

  /// How CLUSTER FAILOVER fails over.
  @since(version = 0.3.0-dev)
  enum cluster-failover-mode {
    /// `FORCE`: without the agreement of the primary, which may be down.
    force,
    /// `TAKEOVER`: without the agreement of the primary or the rest of the cluster.
    takeover,
  }

  /// Which way a slot migration moves the slots.
  @since(version = 0.3.0-dev)
  enum cluster-getslotmigrations-operation {
    /// `IMPORT`: to this node.
    %import,
    /// `EXPORT`: from this node.
    %export,
  }

  /// A slot migration, see `cluster-getslotmigrations`.
  @since(version = 0.3.0-dev)
  record cluster-getslotmigrations-entry {
    /// The ID of the migration.
    link-name: string,
    operation: cluster-getslotmigrations-operation,
    /// The ranges of slots, start and end both included.
    slot-ranges: list<tuple<u16, u16>>,
    /// The ID of the node the slots move to.
    target-node: string,
    /// The ID of the node the slots move from.
    source-node: string,
    create-time: unix-time-seconds,
    last-update-time: unix-time-seconds,
    last-ack-time: unix-time-seconds,
    /// The state of the migration, for people to read.
    state: string,
    /// More details of the state, for people to read.
    message: string,
    /// The bytes copied on write while forked for the migration.
    cow-size: integer,
  }

  /// Ranges of slots to migrate to a node, see `cluster-migrateslots`.
  @since(version = 0.3.0-dev)
  record cluster-migrateslots-group {
    /// The ranges of slots, start and end both included.
    ranges: list<tuple<u16, u16>>,
    /// The ID of the node to migrate the slots to.
    node-id: string,
    /// `AUTH username password`: the credentials for the node, since Valkey 9.2.
    auth: option<tuple<string, string>>,
  }

  /// How CLUSTER RESET resets a node.
  @since(version = 0.3.0-dev)
  enum cluster-reset-mode {
    /// `HARD`: also generates a new node ID and resets the epochs.
    hard,
    /// `SOFT`: the default.
    soft,
  }

  /// The state to set a slot to, see `cluster-setslot`.
  @since(version = 0.3.0-dev)
  variant cluster-setslot-state {
    /// `IMPORTING node-id`: importing the slot from the node.
    importing(string),
    /// `MIGRATING node-id`: migrating the slot to the node.
    migrating(string),
    /// `NODE node-id`: assigned to the node.
    node(string),
    /// `STABLE`: neither importing nor migrating.
    stable,
  }

  /// A command log, see `commandlog-get`.
  @since(version = 0.3.0-dev)
  enum commandlog-type {
    /// `slow`: commands that took longer than `commandlog-execution-slower-than`.
    slow,
    /// `large-request`: commands larger than `commandlog-request-larger-than`.
    large-request,
    /// `large-reply`: replies larger than `commandlog-reply-larger-than`.
    large-reply,
  }

  /// An entry of the slow log or a command log.
  @since(version = 0.3.0-dev)
  record commandlog-entry {
    /// The ID of the entry, unique until the server restarts.
    id: integer,
    /// When the command ran.
    timestamp: unix-time-seconds,
    /// The microseconds the command took, or for the large logs, the bytes of the request or
    /// reply.
    value: integer,
    /// The command and its arguments, long ones shortened.
    arguments: list<string>,
    /// The client's address, `ip:port`.
    client-address: string,
    /// The client's name, see CLIENT SETNAME, empty when it has none.
    client-name: string,
  }

  /// An entry of the slow log, see `slowlog-get`.
  @since(version = 0.3.0-dev)
  type slowlog-entry = commandlog-entry;

  /// Where FAILOVER fails over to.
  @since(version = 0.3.0-dev)
  record failover-target {
    host: string,
    port: u16,
    /// `FORCE`: fails over at the timeout, even before the replica has caught up.
    force: bool,
  }

  /// The latency histogram of a command, see `latency-histogram`.
  @since(version = 0.3.0-dev)
  record latency-histogram-entry {
    /// The number of times the command ran.
    calls: integer,
    /// The cumulative counts of the calls that took up to each number of microseconds, a power
    /// of 2.
    histogram-usec: list<tuple<integer, integer>>,
  }

  /// The latest sample of the latency of an event, see `latency-latest`.
  @since(version = 0.3.0-dev)
  record latency-latest-entry {
    event: string,
    /// When the latest sample was taken.
    timestamp: unix-time-seconds,
    latest: duration-milliseconds,
    /// The highest latency since the server started, or the event was reset.
    max: duration-milliseconds,
    /// The sum of the latencies of the samples.
    sum: duration-milliseconds,
    /// The number of samples.
    count: integer,
  }

  /// A loaded module, see `module-list`.
  @since(version = 0.3.0-dev)
  record module-list-entry {
    name: string,
    /// The module's version.
    ver: integer,
    /// The path the module was loaded from.
    path: string,
    /// The arguments the module was loaded with.
    args: list<string>,
  }

  /// A replica of a primary, see `role`.
  @since(version = 0.3.0-dev)
  record role-primary-replica {
    ip: string,
    port: u16,
    /// The replication offset the replica last acknowledged.
    offset: integer,
  }

  /// The replication state of a primary, see `role`.
  @since(version = 0.3.0-dev)
  record role-primary {
    /// The primary's replication offset.
    offset: integer,
    replicas: list<role-primary-replica>,
  }

  /// The replication state of a replica, see `role`.
  @since(version = 0.3.0-dev)
  record role-replica {
    primary-host: string,
    primary-port: u16,
    /// The state of replication, e.g. `connected`, `connecting` or `sync`.
    state: string,
    /// The replication offset of the data received from the primary, -1 when not connected.
    offset: integer,
  }

  /// The server's role in replication, see `role`.
  @since(version = 0.3.0-dev)
  variant role-reply {
    /// `master`
    primary(role-primary),
    /// `slave`
    replica(role-replica),
    /// `sentinel`: the names of the primaries it monitors.
    sentinel(list<string>),
  }

  /// The modifiers of SHUTDOWN.
  @since(version = 0.3.0-dev)
  flags shutdown-flags {
    /// `NOW`: does not wait for lagging replicas.
    now,
    /// `FORCE`: ignores errors that would prevent the shutdown, e.g. failing to save.
    force,
    /// `SAFE`: refuses to shut down while it would lose the cluster's quorum of primaries.
    safe,
    /// `FAILOVER`: fails over to a replica first.
    failover,
  }

  /// Whether SHUTDOWN saves to disk.
  @since(version = 0.3.0-dev)
  enum shutdown-save {
    /// `NOSAVE`: does not save, even with save points configured.
    nosave,
    /// `SAVE`: saves, even without save points configured.
    save,
  }

  /// A rule for the keys a user may access.
  @since(version = 0.3.0-dev)
  variant acl-key-rule {
    /// `~<pattern>`: allows reading and writing the keys matching the glob-style pattern.
    add(string),
    /// `%R~<pattern>`: allows reading the keys matching the glob-style pattern.
    add-read(string),
    /// `%W~<pattern>`: allows writing the keys matching the glob-style pattern.
    add-write(string),
    /// `%RW~<pattern>`: allows reading and writing the keys matching the glob-style pattern, the
    /// same as `add`.
    add-read-write(string),
    /// `allkeys`: allows access to all keys, an alias for `~*`.
    all,
    /// `resetkeys`: removes all the allowed key patterns.
    reset,
  }

  /// A rule for the Pub/Sub channels a user may access.
  @since(version = 0.3.0-dev)
  variant acl-channel-rule {
    /// `&<pattern>`: allows access to the Pub/Sub channels matching the glob-style pattern.
    add(string),
    /// `allchannels`: allows access to all Pub/Sub channels, an alias for `&*`.
    all,
    /// `resetchannels`: removes all the allowed channel patterns, disconnecting the user's Pub/Sub
    /// clients that can no longer access their channels.
    reset,
  }

  /// A rule for the commands a user may call.
  @since(version = 0.3.0-dev)
  variant acl-command-rule {
    /// `+<command>`: allows the command, or a subcommand, e.g. `config|get`.
    add(string),
    /// `+@<category>`: allows all the commands in the category, e.g. `read`, see ACL CAT for the
    /// categories.
    add-category(string),
    /// `+<command>|<first-arg>`: allows the command only with the given first argument, e.g. `select`
    /// with `0`.
    add-first-arg(tuple<string, string>),
    /// `allcommands`: allows all commands, including those of modules loaded later, an alias for `+@all`.
    all,
    /// `-<command>`: disallows the command, or a subcommand.
    remove(string),
    /// `-@<category>`: disallows all the commands in the category.
    remove-category(string),
    /// `nocommands`: disallows all commands, an alias for `-@all`.
    reset,
  }

  /// A rule for the databases a user may access.
  @since(version = 0.3.0-dev)
  variant acl-db-rule {
    /// `db=<id>[,<id>...]`: allows access to the databases with the given IDs.
    db(list<u8>),
    /// `alldbs`: allows access to all databases.
    all,
    /// `resetdbs`: removes all the allowed databases.
    reset,
  }

  /// A rule of a selector, a set of permissions matched independently of the user's root permissions,
  /// the user may run a command when either permits it.
  @since(version = 0.3.0-dev)
  variant acl-selector-rule {
    /// The keys the selector permits access to.
    keys(acl-key-rule),
    /// The Pub/Sub channels the selector permits access to.
    channel(acl-channel-rule),
    /// The commands the selector permits.
    command(acl-command-rule),
    /// The databases the selector permits access to.
    db(acl-db-rule),
    /// A rule this interface does not know, e.g. from a newer server, sent as is.
    other(string),
  }

  /// A rule for the user itself.
  @since(version = 0.3.0-dev)
  variant acl-user-rule {
    /// `on`: enables the user, it is possible to authenticate as this user.
    on,
    /// `off`: disables the user, it is no longer possible to authenticate as this user, connections
    /// already authenticated keep working.
    off,
    /// `nopass`: removes all the user's passwords, any password then authenticates as the user.
    nopass,
    /// `sanitize-payload`: validates the payloads of the user's RESTORE commands, the default.
    sanitize-payload,
    /// `skip-sanitize-payload`: skips validating the payloads of the user's RESTORE commands.
    skip-sanitize-payload,
    /// `><password>`: adds the password to the user's passwords.
    password(string),
    /// `#<hash>`: adds a password, by its SHA-256 hash as 64 lowercase hex characters, to the user's
    /// passwords.
    hashed-password(string),
    /// `<<password>`: removes the password from the user's passwords.
    remove-password(string),
    /// `!<hash>`: removes a password, by its SHA-256 hash, from the user's passwords.
    remove-hashed-password(string),
    /// `(<rule> ...)`: adds a selector, with the given rules.
    selector(list<acl-selector-rule>),
    /// `clearselectors`: removes all the user's selectors.
    clearselectors,
    /// `reset`: resets the user to its state when created, disabled, without passwords, keys,
    /// channels, commands or selectors.
    reset,
  }

  /// A rule of an ACL user, see `acl-setuser`.
  ///
  /// https://valkey.io/topics/acl/
  @since(version = 0.3.0-dev)
  variant acl-rule {
    /// The keys the user may access.
    keys(acl-key-rule),
    /// The Pub/Sub channels the user may access.
    channel(acl-channel-rule),
    /// The commands the user may call.
    command(acl-command-rule),
    /// The databases the user may access.
    db(acl-db-rule),
    /// The user itself, e.g. whether it is enabled and its passwords.
    user(acl-user-rule),
    /// A rule this interface does not know, e.g. from a newer server, sent as is.
    other(string),
  }

  /// A user and its rules, see `acl-list`.
  @since(version = 0.3.0-dev)
  record acl-list-entry {
    username: string,
    /// The user's rules, as the server normalized them, e.g. `allkeys` is `~*`. Applied with
    /// `acl-setuser`, after `reset`, they recreate the user.
    rules: list<acl-rule>,
  }

  /// bitmap commands
  /// A range of a string, negative from the end, for BITCOUNT and BITPOS.
  @since(version = 0.3.0-dev)
  variant bit-range {
    /// `start`: the bytes from the start to the end of the string.
    %from(integer),
    /// `start end`: the bytes from the start to the end, both included.
    bytes(tuple<integer, integer>),
    /// `start end BIT`: the bits from the start to the end, both included.
    bits(tuple<integer, integer>),
  }

  /// The type of an integer field of a string, for BITFIELD.
  @since(version = 0.3.0-dev)
  variant bitfield-encoding {
    /// `i1` to `i64`: a signed integer of the width in bits.
    signed(u8),
    /// `u1` to `u63`: an unsigned integer of the width in bits.
    unsigned(u8),
  }

  /// Where an integer field of a string starts, for BITFIELD.
  @since(version = 0.3.0-dev)
  variant bitfield-offset {
    /// The offset in bits.
    bit(u64),
    /// `#field`: the field of the encoding's width, the offset in bits is the field times the
    /// width.
    field(u64),
  }

  /// What a write does when the field overflows, `OVERFLOW`.
  @since(version = 0.3.0-dev)
  enum bitfield-overflow {
    /// `WRAP`: wraps around, the default.
    wrap,
    /// `SAT`: saturates at the minimum or maximum.
    sat,
    /// `FAIL`: does not write, the result is none.
    fail,
  }

  /// `GET encoding offset`: the value of the field.
  @since(version = 0.3.0-dev)
  record bitfield-get {
    encoding: bitfield-encoding,
    offset: bitfield-offset,
  }

  /// A GET operation, see `bitfield-ro`.
  @since(version = 0.3.0-dev)
  type bitfield-ro-get = bitfield-get;

  /// `SET encoding offset value`: sets the field, the result is its previous value.
  @since(version = 0.3.0-dev)
  record bitfield-set {
    encoding: bitfield-encoding,
    offset: bitfield-offset,
    value: s64,
  }

  /// `INCRBY encoding offset increment`: increments the field, the result is its new value.
  @since(version = 0.3.0-dev)
  record bitfield-incrby {
    encoding: bitfield-encoding,
    offset: bitfield-offset,
    increment: s64,
  }

  /// An operation of BITFIELD.
  ///
  /// A write is preceded by an optional overflow mode, `OVERFLOW WRAP | SAT | FAIL`, for it and
  /// the following writes. None keeps the current mode, `WRAP` at the start of the command.
  @since(version = 0.3.0-dev)
  variant bitfield-operation {
    /// `GET encoding offset`
    get(bitfield-get),
    /// `[ OVERFLOW WRAP | SAT | FAIL ] SET encoding offset value`
    set(tuple<option<bitfield-overflow>, bitfield-set>),
    /// `[ OVERFLOW WRAP | SAT | FAIL ] INCRBY encoding offset increment`
    incrby(tuple<option<bitfield-overflow>, bitfield-incrby>),
  }

  /// A bitwise operation of BITOP, and its source keys.
  @since(version = 0.3.0-dev)
  variant bitop-operation {
    /// `AND`
    and(list<string>),
    /// `OR`
    or(list<string>),
    /// `XOR`
    xor(list<string>),
    /// `NOT`: of a single key.
    not(string),
  }

  /// The keyword before the first key, see `command-key-spec-begin-search`.
  @since(version = 0.3.0-dev)
  record command-key-spec-keyword {
    keyword: string,
    /// The index of the argument to start searching from, from the end when negative.
    startfrom: integer,
  }

  /// connection commands
  /// How a key spec finds the first key, see `command-key-spec`.
  @since(version = 0.3.0-dev)
  variant command-key-spec-begin-search {
    /// `index`: the argument at the index.
    index(integer),
    /// `keyword`: the argument after the keyword.
    keyword(command-key-spec-keyword),
    /// `unknown`: the keys cannot be found from the arguments alone.
    unknown,
  }

  /// A range of keys, see `command-key-spec-find-keys`.
  @since(version = 0.3.0-dev)
  record command-key-spec-range {
    /// The index of the last key, relative to the first, from the end when negative.
    lastkey: integer,
    /// The number of arguments from one key to the next.
    keystep: integer,
    /// With a `lastkey` of -1, divides the remaining arguments, e.g. 2 for half of them.
    limit: integer,
  }

  /// A number of keys, see `command-key-spec-find-keys`.
  @since(version = 0.3.0-dev)
  record command-key-spec-keynum {
    /// The index of the argument with the number of keys, relative to the first.
    keynumidx: integer,
    /// The index of the first key, relative to the first.
    firstkey: integer,
    /// The number of arguments from one key to the next.
    keystep: integer,
  }

  /// How a key spec finds the keys after the first one, see `command-key-spec`.
  @since(version = 0.3.0-dev)
  variant command-key-spec-find-keys {
    /// `range`: a range of arguments.
    range(command-key-spec-range),
    /// `keynum`: the number of keys is an argument.
    keynum(command-key-spec-keynum),
    /// `unknown`: the keys cannot be found from the arguments alone.
    unknown,
  }

  /// Where a command's keys are and how it uses them.
  @since(version = 0.3.0-dev)
  record command-key-spec {
    notes: option<string>,
    /// How the command uses the keys, e.g. `RW`, `access` and `update`.
    %flags: list<string>,
    begin-search: command-key-spec-begin-search,
    find-keys: command-key-spec-find-keys,
  }

  /// A command, see `command` and `command-info`.
  @since(version = 0.3.0-dev)
  record command-info-reply {
    /// The command's name, e.g. `get`, or for a subcommand, `config|get`.
    name: string,
    /// The number of arguments, the name included, the minimum when negative.
    arity: integer,
    /// The command's flags, e.g. `readonly` and `fast`.
    %flags: list<string>,
    /// The index of the first key, 0 for none.
    first-key: integer,
    /// The index of the last key, from the end when negative.
    last-key: integer,
    /// The number of arguments from one key to the next.
    step: integer,
    /// The ACL categories of the command, e.g. `@read`.
    acl-categories: list<string>,
    /// Hints for clients, e.g. `nondeterministic_output`.
    tips: list<string>,
    key-specs: list<command-key-spec>,
  }

  /// The details of a command, see `command`.
  @since(version = 0.3.0-dev)
  type command-reply = command-info-reply;

  /// The type of an argument of a command, see `command-docs-argument`.
  @since(version = 0.3.0-dev)
  variant command-docs-argument-type {
    /// `string`
    %string,
    /// `integer`
    integer,
    /// `double`
    double,
    /// `key`: a key, see `key-spec-index`.
    key,
    /// `pattern`: a glob-style pattern.
    pattern,
    /// `unix-time`
    unix-time,
    /// `pure-token`: the token alone, without a value.
    pure-token,
    /// `oneof`: one of the arguments it contains.
    oneof,
    /// `block`: the arguments it contains, together.
    block,
    /// A type this interface does not know, e.g. from a newer server.
    other(string),
  }

  /// An argument of a command, see `command-docs`.
  @since(version = 0.3.0-dev)
  record command-docs-argument {
    /// The index of the `oneof` or `block` argument containing this one, in the command's
    /// arguments, none at the top level.
    parent: option<u32>,
    name: string,
    %type: command-docs-argument-type,
    /// The name to show for the argument.
    display-text: option<string>,
    /// The index of the argument's key spec, for a key.
    key-spec-index: option<integer>,
    /// The token before the argument's value, e.g. `EX`, or for a `pure-token`, the token alone.
    token: option<string>,
    summary: option<string>,
    /// The version that added the argument.
    since: option<string>,
    deprecated-since: option<string>,
    /// The argument's flags, e.g. `optional`, `multiple` and `multiple_token`.
    %flags: list<string>,
  }

  /// The documentation of a command, see `command-docs`.
  @since(version = 0.3.0-dev)
  record command-docs-reply {
    /// The command's name, e.g. `get`, or for a subcommand, `config|get`.
    name: string,
    summary: string,
    /// The version that added the command.
    since: string,
    /// The command's group, e.g. `string`.
    group: string,
    /// The command's time complexity, none for a few commands, e.g. MONITOR.
    complexity: option<string>,
    /// The module of the command, for a module's command.
    module: option<string>,
    /// The command's documentation flags, e.g. `deprecated` or `syscmd`.
    doc-flags: list<string>,
    deprecated-since: option<string>,
    /// The command to use instead, for a deprecated command.
    replaced-by: option<string>,
    /// The changes to the command, the version of each and what changed.
    history: list<tuple<string, string>>,
    /// The arguments, depth first, those an argument contains after it.
    arguments: list<command-docs-argument>,
  }

  /// Information about the library of a connection, see `client-setinfo`.
  @since(version = 0.3.0-dev)
  variant client-setinfo-attr {
    /// `LIB-NAME`: the name of the library, e.g. `valkey-wasm`.
    lib-name(string),
    /// `LIB-VER`: the version of the library.
    lib-ver(string),
  }

  /// Which keys tracking tracks without CLIENT CACHING.
  @since(version = 0.3.0-dev)
  enum client-tracking-mode {
    /// `OPTIN`: none, only those of commands after CLIENT CACHING YES.
    optin,
    /// `OPTOUT`: all, except those of commands after CLIENT CACHING NO.
    optout,
  }

  /// The options of CLIENT TRACKING ON.
  @since(version = 0.3.0-dev)
  record client-tracking-options {
    /// `PREFIX prefix`: with `bcast`, only notifies about keys with the prefixes.
    prefixes: option<list<string>>,
    /// `BCAST`: notifies about every change of the keys with the prefixes, read or not.
    bcast: bool,
    mode: option<client-tracking-mode>,
    /// `NOLOOP`: does not notify about the keys the connection changed itself.
    noloop: bool,
  }

  /// Where a connection's tracking notifications are redirected, see `client-trackinginfo`.
  ///
  /// Redirecting is for RESP2, which the connection does not use, but CLIENT TRACKING REDIRECT may
  /// still be sent with `connection.exchange`.
  @since(version = 0.3.0-dev)
  variant client-trackinginfo-redirect {
    /// -1: tracking is not on.
    not-tracking,
    /// 0: tracking is on, the notifications are not redirected.
    not-redirected,
    /// The ID of the connection the notifications are redirected to.
    redirected(integer),
  }

  /// A connection's tracking state, see `client-trackinginfo`.
  @since(version = 0.3.0-dev)
  record client-trackinginfo-reply {
    /// The tracking flags, e.g. `on`, `bcast`, `optin` or `noloop`.
    %flags: list<string>,
    /// Where the notifications are redirected.
    redirect: client-trackinginfo-redirect,
    /// The prefixes of BCAST.
    prefixes: list<string>,
  }

  /// The filter of COMMAND LIST.
  @since(version = 0.3.0-dev)
  variant command-list-filter {
    /// `MODULE module-name`: the commands of the module.
    module(string),
    /// `ACLCAT category`: the commands in the ACL category.
    aclcat(string),
    /// `PATTERN pattern`: the commands matching the glob-style pattern.
    pattern(string),
  }

  /// geo commands
  /// A position on the Earth.
  ///
  /// The exact limits, as specified by EPSG:900913 / EPSG:3785 / OSGEO:41001
  @since(version = 0.3.0-dev)
  record geo-coordinates {
    /// The longitude, from -180 to 180 degrees.
    longitude: double,
    /// The latitude, from -85.05112878 to 85.05112878 degrees.
    latitude: double,
  }

  /// A unit of distance.
  @since(version = 0.3.0-dev)
  enum geo-unit {
    /// `m`: meters.
    m,
    /// `km`: kilometers.
    km,
    /// `ft`: feet.
    ft,
    /// `mi`: miles.
    mi,
  }

  /// Only add or only update members, GEOADD's `NX` and `XX`.
  @since(version = 0.3.0-dev)
  enum geoadd-condition {
    /// Only add new members, never update existing ones.
    nx,
    /// Only update existing members, never add new ones.
    xx,
  }

  /// The center of a search, `FROMMEMBER` or `FROMLONLAT`.
  @since(version = 0.3.0-dev)
  variant geosearch-from {
    /// `FROMMEMBER member`: the position of a member of the index.
    member(string-or-bytes),
    /// `FROMLONLAT longitude latitude`
    lonlat(geo-coordinates),
  }

  /// `BYRADIUS`: a circle around the center.
  @since(version = 0.3.0-dev)
  record geosearch-radius {
    %from: geosearch-from,
    radius: double,
    unit: geo-unit,
  }

  /// `BYBOX`: a rectangle around the center.
  @since(version = 0.3.0-dev)
  record geosearch-box {
    %from: geosearch-from,
    width: double,
    height: double,
    unit: geo-unit,
  }

  /// The area of a search.
  @since(version = 0.3.0-dev)
  variant geosearch-shape {
    /// `[ FROMMEMBER member | FROMLONLAT longitude latitude ] BYRADIUS radius unit`
    radius(geosearch-radius),
    /// `[ FROMMEMBER member | FROMLONLAT longitude latitude ] BYBOX width height unit`
    box(geosearch-box),
    /// `BYPOLYGON num-vertices longitude latitude [ longitude latitude ... ]`: the polygon with
    /// the vertices, in order, which has no center.
    polygon(list<geo-coordinates>),
  }

  /// The area to search, see `geosearchstore`.
  @since(version = 0.3.0-dev)
  type geosearchstore-shape = geosearch-shape;

  /// At most a count of the members, `COUNT count [ ANY ]`.
  @since(version = 0.3.0-dev)
  record geosearch-count {
    count: integer,
    /// `ANY`: returns as soon as enough members are found, rather than the nearest ones.
    any: bool,
  }

  /// The number of members to store, see `geosearchstore`.
  @since(version = 0.3.0-dev)
  type geosearchstore-count = geosearch-count;

  /// The details GEOSEARCH returns of each member it found.
  @since(version = 0.3.0-dev)
  flags geosearch-with-flags {
    /// `WITHCOORD`: the position.
    withcoord,
    /// `WITHDIST`: the distance from the center.
    withdist,
    /// `WITHHASH`: the geohash, as an integer.
    withhash,
  }

  /// A member a search found, with the details asked for.
  @since(version = 0.3.0-dev)
  record geosearch-with-result {
    member: string-or-bytes,
    /// `WITHDIST`: the distance from the center, in the unit of the shape.
    distance: option<double>,
    /// `WITHHASH`: the geohash, as an integer.
    hash: option<integer>,
    /// `WITHCOORD`: the position.
    coordinates: option<geo-coordinates>,
  }

  /// hash commands
  /// The outcome of removing the expiration of a hash field.
  @since(version = 0.3.0-dev)
  enum hpersist-result {
    /// -2: the field does not exist, or the hash does not exist.
    does-not-exist,
    /// -1: the field exists, but has no expiration.
    no-expiration,
    /// 1: the expiration was removed.
    removed,
  }

  /// Only set the fields when the hash does, or does not, exist, HSETEX's `NX` and `XX`.
  @since(version = 0.3.0-dev)
  enum hsetex-condition {
    /// Only set the fields when the hash does not exist.
    nx,
    /// Only set the fields when the hash exists.
    xx,
  }

  /// Only set the fields when none, or all, of them exist, HSETEX's `FNX` and `FXX`.
  @since(version = 0.3.0-dev)
  enum hsetex-field-condition {
    /// Only set the fields when none of them exist.
    fnx,
    /// Only set the fields when all of them exist.
    fxx,
  }

  /// The outcome of setting the expiration of a hash field, e.g. with HEXPIRE.
  @since(version = 0.3.0-dev)
  enum hexpire-result {
    /// -2: key does not exist, or field does not exist in the HASH.
    does-not-exist,
    /// 0: the specified NX | XX | GT | LT condition has not been met.
    condition-not-met,
    /// 1: the expiration time was applied.
    applied,
    /// 2: when called with 0 seconds.
    zero-seconds,
  }

  /// The result for a field, see `hexpireat`.
  @since(version = 0.3.0-dev)
  type hexpireat-result = hexpire-result;

  /// The result for a field, see `hpexpire`.
  @since(version = 0.3.0-dev)
  type hpexpire-result = hexpire-result;

  /// The result for a field, see `hpexpireat`.
  @since(version = 0.3.0-dev)
  type hpexpireat-result = hexpire-result;

  /// keyspace commands
  /// The expiration of a key `restore` creates.
  @since(version = 0.3.0-dev)
  variant restore-ttl {
    /// `ttl`: the key expires after the duration.
    expire-in(duration-milliseconds),
    /// `ttl` with `ABSTTL`: the key expires at the time.
    expire-at(unix-time-milliseconds),
  }

  /// The type of the value stored at a key.
  @since(version = 0.3.0-dev)
  variant key-type {
    /// `string`
    %string,
    /// `list`
    %list,
    /// `set`
    set,
    /// `zset`: a sorted set.
    zset,
    /// `hash`
    hash,
    /// `stream`
    %stream,
    /// The type of a module, by name.
    other(string),
  }

  /// The options of MIGRATE.
  @since(version = 0.3.0-dev)
  flags migrate-flags {
    /// `COPY`: keeps the keys in this instance.
    copy,
    /// `REPLACE`: replaces keys that exist in the other instance.
    replace,
  }

  /// The credentials to authenticate to the other instance with, for MIGRATE.
  @since(version = 0.3.0-dev)
  variant migrate-auth {
    /// `AUTH password`
    password(string),
    /// `AUTH2 username password`
    username-password(tuple<string, string>),
  }

  /// How SORT orders and projects the elements of a list, set or sorted set.
  @since(version = 0.3.0-dev)
  record sort-opts {
    /// `BY pattern`: sorts by the values of the keys the pattern names, `*` replaced with each
    /// element, or `nosort` to skip sorting.
    by: option<string>,
    /// `LIMIT offset count`: a range of the sorted elements.
    limit: option<limit>,
    /// `GET pattern`: returns the values of the keys each pattern names instead of the elements,
    /// `#` for the element itself.
    get: option<list<string>>,
    /// order to sort elements.
    order: option<sort-order>,
    /// `ALPHA`: sorts lexicographically, rather than numerically.
    alpha: bool,
  }

  /// The options of the sort, see `sort-ro`.
  @since(version = 0.3.0-dev)
  type sort-ro-opts = sort-opts;

  /// list commands
  /// An end of a list.
  @since(version = 0.3.0-dev)
  enum list-side {
    /// `LEFT`: the head, the first element.
    left,
    /// `RIGHT`: the tail, the last element.
    right,
  }

  /// Where LINSERT inserts an element, relative to the pivot.
  @since(version = 0.3.0-dev)
  enum linsert-position {
    /// `BEFORE`: in front of the pivot.
    before,
    /// `AFTER`: behind the pivot.
    after,
  }

  /// The outcome of LINSERT.
  @since(version = 0.3.0-dev)
  variant linsert-result {
    /// The element was inserted, the length of the list after it.
    inserted(integer),
    /// 0: the key does not exist, nothing was inserted.
    no-such-key,
    /// -1: the pivot is not in the list, nothing was inserted.
    pivot-not-found,
  }

  /// scripting commands
  /// What `function-restore` does with the libraries already loaded.
  @since(version = 0.3.0-dev)
  enum function-restore-policy {
    /// `FLUSH`: deletes them first.
    flush,
    /// `APPEND`: keeps them, failing when a library of the same name is loaded.
    append,
    /// `REPLACE`: keeps them, replacing those with a library of the same name.
    replace,
  }

  /// Whether a flush happens in the background, `ASYNC`, or before replying, `SYNC`.
  @since(version = 0.3.0-dev)
  enum flush-mode {
    /// `ASYNC`
    %async,
    /// `SYNC`
    sync,
  }

  /// A function of a library.
  @since(version = 0.3.0-dev)
  record function-list-function {
    name: string,
    description: option<string>,
    /// The function's flags, e.g. `no-writes`.
    %flags: list<string>,
  }

  /// A library of functions.
  @since(version = 0.3.0-dev)
  record function-list-library {
    library-name: string,
    /// The engine that runs the library, e.g. `LUA`.
    engine: string,
    functions: list<function-list-function>,
    /// The library's source code, with `withcode`.
    library-code: option<string>,
  }

  /// The function that is running.
  @since(version = 0.3.0-dev)
  record function-stats-running {
    name: string,
    /// The command and its arguments that called the function.
    command: list<string>,
    /// How long the function has been running.
    duration: duration-milliseconds,
  }

  /// The libraries and functions of an engine.
  @since(version = 0.3.0-dev)
  record function-stats-engine {
    libraries-count: integer,
    functions-count: integer,
  }

  /// The function that is running, and the libraries and functions of each engine.
  @since(version = 0.3.0-dev)
  record function-stats-reply {
    /// None when no function is running.
    running-script: option<function-stats-running>,
    /// The statistics of each engine, by name.
    engines: map<string, function-stats-engine>,
  }

  /// sortedset commands
  /// A bound of a range of scores.
  @since(version = 0.3.0-dev)
  variant score-bound {
    /// The score, included in the range.
    inclusive(double),
    /// `(score`: the score, excluded from the range.
    exclusive(double),
    /// `-inf` as the min, `+inf` as the max, the start is the max with `REV`.
    unbounded,
  }

  /// A bound of a range of members, for members of equal score, ordered lexicographically.
  @since(version = 0.3.0-dev)
  variant lex-bound {
    /// `[member`: the member, included in the range.
    inclusive(string-or-bytes),
    /// `(member`: the member, excluded from the range.
    exclusive(string-or-bytes),
    /// `-` as the min, `+` as the max, the start is the max with `REV`.
    unbounded,
  }

  /// Which end of a sorted set to pop from.
  @since(version = 0.3.0-dev)
  enum zmpop-end {
    /// The members with the lowest scores.
    min,
    /// The members with the highest scores.
    max,
  }

  /// The end to pop from, see `bzmpop`.
  @since(version = 0.3.0-dev)
  type bzmpop-end = zmpop-end;

  /// How scores combine for a member in several sorted sets.
  @since(version = 0.3.0-dev)
  enum zset-aggregate {
    /// The sum of the weighted scores, the default.
    sum,
    /// The lowest weighted score.
    min,
    /// The highest weighted score.
    max,
  }

  /// The range of ZRANGE and ZRANGESTORE, `start` and `stop`, given as they are sent: with `REV`,
  /// the higher bound first.
  @since(version = 0.3.0-dev)
  variant zrange-by {
    /// Positions, both included, negative from the end.
    rank(tuple<integer, integer>),
    /// `BYSCORE`: the members with scores in the range.
    score(tuple<score-bound, score-bound>),
    /// `BYLEX`: the members in the range, for members of equal score.
    lex(tuple<lex-bound, lex-bound>),
  }

  /// The range of members to store, see `zrangestore`.
  @since(version = 0.3.0-dev)
  type zrangestore-by = zrange-by;

  /// The range of ZRANGE WITHSCORES, which does not support BYLEX, see `zrange-by`.
  @since(version = 0.3.0-dev)
  variant zrange-withscores-by {
    /// Positions, both included, negative from the end.
    rank(tuple<integer, integer>),
    /// `BYSCORE`: the members with scores in the range.
    score(tuple<score-bound, score-bound>),
  }

  /// Only update or only add members, ZADD's `NX` and `XX`.
  @since(version = 0.3.0-dev)
  enum zadd-condition {
    /// Only add new members, never update existing ones.
    nx,
    /// Only update existing members, never add new ones.
    xx,
  }

  /// Only update a member's score when the new score is greater or less, ZADD's `GT` and `LT`.
  @since(version = 0.3.0-dev)
  enum zadd-comparison {
    /// Only update when the new score is greater than the current one.
    gt,
    /// Only update when the new score is less than the current one.
    lt,
  }

  /// stream commands
  /// The ID of a stream entry, `<milliseconds-time>-<sequence-number>`, e.g. `1526919030474-55`.
  ///
  /// Commands that add an entry also accept `*`, for the server to generate the ID.
  @since(version = 0.3.0-dev)
  type stream-id = string;

  /// How exactly a stream is trimmed. Nearly exact trimming is more efficient, the stream may keep a
  /// few entries more than the threshold.
  @since(version = 0.3.0-dev)
  enum stream-trim-efficiency {
    /// `=`: exact trimming
    exact,
    /// `~`: nearly exact trimming
    mearly-exact,
  }

  /// Trims the stream to a maximum length, `MAXLEN [ = | ~ ] threshold [ LIMIT count ]`.
  @since(version = 0.3.0-dev)
  record stream-trim-maxlen {
    /// Exact, `=`, when none.
    efficiency: option<stream-trim-efficiency>,
    /// The maximum number of entries kept.
    threshold: integer,
    /// The maximum number of entries evicted, only with nearly exact trimming, `0` for no limit.
    limit: option<integer>,
  }

  /// Trims the entries with lower IDs, `MINID [ = | ~ ] threshold [ LIMIT count ]`.
  @since(version = 0.3.0-dev)
  record stream-trim-minid {
    /// Exact, `=`, when none.
    efficiency: option<stream-trim-efficiency>,
    /// The lowest ID kept.
    threshold: stream-id,
    /// The maximum number of entries evicted, only with nearly exact trimming, `0` for no limit.
    limit: option<integer>,
  }

  /// How a stream is trimmed, e.g. with XADD or XTRIM.
  @since(version = 0.3.0-dev)
  variant stream-trim {
    /// Evicts entries as long as the stream's length exceeds the specified threshold, where threshold is a positive integer.
    maxlen(stream-trim-maxlen),
    /// Evicts entries with IDs lower than threshold, where threshold is a stream ID.
    minid(stream-trim-minid),
  }

  /// Options of XCLAIM.
  @since(version = 0.3.0-dev)
  record xclaim-opts {
    /// `IDLE ms`: sets the idle time of the entries, the time since they were last delivered, instead
    /// of resetting it.
    idle: option<duration-milliseconds>,
    /// `TIME unix-time-milliseconds`: sets the idle time of the entries to the time since this instant.
    time: option<unix-time-milliseconds>,
    /// `RETRYCOUNT count`: sets the delivery count of the entries, instead of incrementing it.
    retrycount: option<integer>,
    /// `FORCE`: claims the entries even when they are not pending for any consumer, as long as they
    /// exist in the stream.
    force: bool,
    /// `LASTID lastid`: sets the ID of the last entry delivered to the group.
    lastid: option<stream-id>,
  }

  /// A consumer of a group, see `xinfo-consumers`.
  @since(version = 0.3.0-dev)
  record xinfo-consumers-entry {
    /// The consumer's name.
    name: string,
    /// The number of entries pending for the consumer.
    pending: integer,
    /// The time since the consumer last attempted an interaction, e.g. XREADGROUP, XCLAIM or
    /// XAUTOCLAIM.
    idle: duration-milliseconds,
    /// The time since the consumer last interacted successfully, e.g. read or claimed entries.
    /// None when the consumer has never been active.
    inactive: option<duration-milliseconds>,
  }

  /// A consumer group of a stream, see `xinfo-groups`.
  @since(version = 0.3.0-dev)
  record xinfo-groups-entry {
    /// The group's name.
    name: string,
    /// The number of consumers in the group.
    consumers: integer,
    /// The number of entries in the group's pending entries list (PEL), delivered but not acknowledged.
    pending: integer,
    /// The ID of the last entry delivered to the group's consumers.
    last-delivered-id: stream-id,
    /// The logical read counter of the last entry delivered to the group's consumers, none when unknown.
    entries-read: option<integer>,
    /// The number of entries in the stream not yet delivered to the group's consumers, none when it
    /// cannot be determined.
    lag: option<integer>,
  }

  /// Information about a stream, see `xinfo-stream`.
  @since(version = 0.3.0-dev)
  record xinfo-stream-reply {
    /// The number of entries in the stream.
    length: integer,
    /// The number of keys in the radix tree storing the stream.
    radix-tree-keys: integer,
    /// The number of nodes in the radix tree storing the stream.
    radix-tree-nodes: integer,
    /// The number of consumer groups of the stream.
    groups: integer,
    /// The ID of the last entry added to the stream, none when no entry was ever added.
    last-generated-id: option<stream-id>,
    /// The highest ID deleted from the stream, none when no entry was ever deleted.
    max-deleted-entry-id: option<stream-id>,
    /// The number of entries added to the stream over its lifetime.
    entries-added: integer,
    /// The ID and fields of the first entry.
    /// None when the stream is empty.
    first-entry: option<tuple<stream-id, map<string, string-or-bytes>>>,
    /// The ID and fields of the last entry.
    /// None when the stream is empty.
    last-entry: option<tuple<stream-id, map<string, string-or-bytes>>>,
  }

  /// A consumer of a group, with its pending entries.
  @since(version = 0.3.0-dev)
  record xinfo-stream-reply-full-consumer {
    /// The consumer's name.
    name: string,
    /// When the consumer last attempted an interaction, e.g. XREADGROUP, XCLAIM or XAUTOCLAIM.
    seen-time: unix-time-milliseconds,
    /// When the consumer last interacted successfully, e.g. read or claimed entries.
    /// None when the consumer has never been active.
    active-time: option<unix-time-milliseconds>,
    /// The number of entries pending for the consumer, delivered but not acknowledged.
    pel-count: integer,
    /// The consumer's pending entries, the ID of each, when it was last delivered and the number of
    /// times it was delivered.
    pending: list<tuple<stream-id, unix-time-milliseconds, integer>>,
  }

  /// A consumer group of a stream, with its pending entries and consumers.
  @since(version = 0.3.0-dev)
  record xinfo-stream-reply-full-group {
    /// The group's name.
    name: string,
    /// The ID of the last entry delivered to the group's consumers.
    last-delivered-id: stream-id,
    /// The logical read counter of the last entry delivered to the group's consumers, none when unknown.
    entries-read: option<integer>,
    /// The number of entries in the stream not yet delivered to the group's consumers, none when it
    /// cannot be determined.
    lag: option<integer>,
    /// The number of entries in the group's pending entries list (PEL), delivered but not acknowledged.
    pel-count: integer,
    /// The group's pending entries, the ID of each, the consumer it was delivered to, when it was
    /// last delivered and the number of times it was delivered.
    pending: list<tuple<stream-id, string, unix-time-milliseconds, integer>>,
    /// The group's consumers.
    consumers: list<xinfo-stream-reply-full-consumer>,
  }

  /// Information about a stream, its entries and consumer groups, see `xinfo-stream-full`.
  @since(version = 0.3.0-dev)
  record xinfo-stream-reply-full {
    /// The number of entries in the stream.
    length: integer,
    /// The number of keys in the radix tree storing the stream.
    radix-tree-keys: integer,
    /// The number of nodes in the radix tree storing the stream.
    radix-tree-nodes: integer,
    /// The ID of the last entry added to the stream, none when no entry was ever added.
    last-generated-id: option<stream-id>,
    /// The highest ID deleted from the stream, none when no entry was ever deleted.
    max-deleted-entry-id: option<stream-id>,
    /// The number of entries added to the stream over its lifetime.
    entries-added: integer,
    /// The ID and fields of the entries, in ascending ID order, up to the count given.
    entries: list<tuple<stream-id, map<string, string-or-bytes>>>,
    /// The consumer groups of the stream.
    groups: list<xinfo-stream-reply-full-group>,
  }

  /// The pending entries of a consumer group, see `xpending`.
  @since(version = 0.3.0-dev)
  record xpending-summary {
    /// The number of pending entries.
    count: integer,
    /// The lowest ID of the pending entries, none when there are none.
    lowest-id: option<stream-id>,
    /// The highest ID of the pending entries, none when there are none.
    highest-id: option<stream-id>,
    /// Each consumer with pending entries, and how many it has.
    consumers: list<tuple<string, integer>>,
  }

  /// The pending entries of a consumer group, see `xpending-extended`.
  @since(version = 0.3.0-dev)
  record xpending-extended-entry {
    /// The ID of the message.
    id: stream-id,
    /// The name of the consumer that fetched the message and has still to acknowledge it. We call it the current owner of the message.
    name: string,
    /// The number of milliseconds that elapsed since the last time this message was delivered to this consumer.
    since-delivery: duration-milliseconds,
    /// The number of times this message was delivered.
    delivery-count: integer,
  }

  /// string commands
  /// The expiration to set on a key, see `getex`.
  @since(version = 0.3.0-dev)
  variant getex-ttl {
    /// Set the specified expire time, in seconds.
    ex(duration-seconds),
    /// Set the specified expire time, in milliseconds.
    px(duration-milliseconds),
    /// Set the specified Unix time at which the key will expire, in seconds.
    exat(unix-time-seconds),
    /// Set the specified Unix time at which the key will expire, in milliseconds.
    pxat(unix-time-milliseconds),
    /// Remove the time to live associated with the key.
    persist,
  }

  /// The expiration to set on the fields, see `hgetex`.
  @since(version = 0.3.0-dev)
  type hgetex-ttl = getex-ttl;

  /// A part of the longest common subsequence.
  @since(version = 0.3.0-dev)
  record lcs-idx-match {
    /// The inclusive start and end positions of the match in the first key's string.
    key1-range: tuple<integer, integer>,
    /// The inclusive start and end positions of the match in the second key's string.
    key2-range: tuple<integer, integer>,
    /// The length of the match, with `with-match-len`.
    len: option<integer>,
  }

  /// The longest common subsequence of two strings, as the ranges matching in each, see `lcs-idx`.
  @since(version = 0.3.0-dev)
  record lcs-idx-reply {
    /// The ranges that match, from the end of the strings to their start.
    matches: list<lcs-idx-match>,
    /// The length of the longest common subsequence.
    len: integer,
  }

  /// The condition for setting the keys, see `msetex`.
  @since(version = 0.3.0-dev)
  variant msetex-precondition {
    /// Only set the keys if all of them do not already exist.
    nx,
    /// Only set the keys if all of them already exist.
    xx,
  }

  /// The condition for setting a key, see `set`.
  @since(version = 0.3.0-dev)
  variant set-precondition {
    /// Only set the key if it does not already exist.
    nx,
    /// Only set the key if it already exists.
    xx,
    /// Set the key if the comparison value matches the existing value.
    ifeq(string-or-bytes),
    /// Set the key if the comparison value does not match the existing value.
    ifne(string-or-bytes),
  }

  /// The expiration to set on a key, see `set`.
  @since(version = 0.3.0-dev)
  variant set-ttl {
    /// Set the specified expire time, in seconds.
    ex(duration-seconds),
    /// Set the specified expire time, in milliseconds.
    px(duration-milliseconds),
    /// Set the specified Unix time at which the key will expire, in seconds.
    exat(unix-time-seconds),
    /// Set the specified Unix time at which the key will expire, in milliseconds.
    pxat(unix-time-milliseconds),
    /// Retain the time to live associated with the keys.
    keepttl,
  }

  /// The expiration to set on the keys, see `msetex`.
  @since(version = 0.3.0-dev)
  type msetex-ttl = set-ttl;

  /// The expiration to set on the fields, see `hsetex`.
  @since(version = 0.3.0-dev)
  type hsetex-ttl = set-ttl;
}