1
0
mirror of https://github.com/redis/node-redis.git synced 2025-08-09 00:22:08 +03:00
This commit is contained in:
Leibale
2023-04-05 13:03:44 -04:00
parent ca1d04f2ba
commit 935993a84a
3 changed files with 137 additions and 0 deletions

32
md/RESP3.md Normal file
View File

@@ -0,0 +1,32 @@
# RESP3 => JS type mapping:
- Null (`_`) => `null`
- Boolean (`#`) => `boolean`
- Number (`:`) => `number | string`
- Big Number (`(`) => `BigInt | string`
- Double (`,`) => `number | string`
- Simple String (`+`) => `string | Buffer`
- Blob String (`$`) => `string | Buffer`
- Verbatim String (`=`) => `string | Buffer | VerbatimString`
- Simple Error (`-`) => `ErrorReply`
- Blob Error (`!`) => `ErrorReply`
- Array (`*`) => `Array`
- Set (`~`) => `Array | Set`
- Map (`%`) => `object | Map | Array`
- Push (`>`) => `Array` => PubSub push/`'push'` event
> NOTE: the first type is the default type
## Verbatim String
## Map keys and Set members
When decoding Map to `Map | object` or Set to `Set`, keys/members of type "Simple String" or "Blob String" will be decode as `string`s (ignoring flags) to allow lookup by type. If you need them as `Buffer`s, make sure to decode `Map`s/`Set`s as `Array`s.
## Not Implemented
These parts of RESP3 are not implemented in Redis itself (at the time of writing this), so we did not implemented them in the client as well:
- [Attribute type](https://github.com/redis/redis-specifications/blob/master/protocol/RESP3.md#attribute-type)
- [Streamed strings](https://github.com/redis/redis-specifications/blob/master/protocol/RESP3.md#streamed-strings)
- [Streamed aggregated data types](https://github.com/redis/redis-specifications/blob/master/protocol/RESP3.md#streamed-aggregated-data-types)

75
md/v4-to-v5.md Normal file
View File

@@ -0,0 +1,75 @@
# v4 to v5 migration guide
## Commands
Some command arguments/replies changed to be more aligned with Redis:
- `ACL GETUSER`: `selectors`
- `CLIENT KILL`: `enum ClientKillFilters` -> `const CLIENT_KILL_FILTERS` [^enum-to-constants]
- `CLUSTER FAILOVER`: `enum FailoverModes` -> `const FAILOVER_MODES` [^enum-to-constants]
- `LCS IDX`: `length` has been changed to `len`, `matches` has been changed from `Array<{ key1: RangeReply; key2: RangeReply; }>` to `Array<[key1: RangeReply, key2: RangeReply]>`
- `HEXISTS`: `boolean` -> `number` [^boolean-to-number]
- `HRANDFIELD_COUNT_WITHVALUES`: `Record<BlobString, BlobString>` -> `Array<{ field: BlobString; value: BlobString; }>` (it can return duplicates).
- `SCAN`, `HSCAN`, `SSCAN`, and `ZSCAN`: cursor type is `string` instead of `number`?
- `HSETNX`: `boolean` -> `number` [^boolean-to-number]
- `ZINTER`: instead of `client.ZINTER('11, { WEIGHTS: [1] })` use `client.ZINTER({ key: '1', weight: 1 }])`
- `SETNX`: `boolean` -> `number` [^boolean-to-number]
- `COPY`: `destinationDb` -> `DB`, `replace` -> `REPLACE`, `boolean` -> `number` [^boolean-to-number]
- `EXPIRE`: `boolean` -> `number` [^boolean-to-number]
- `EXPIREAT`: `boolean` -> `number` [^boolean-to-number]
- `MOVE`: `boolean` -> `number` [^boolean-to-number]
- `PEXPIRE`: `boolean` -> `number` [^boolean-to-number]
- `PEXPIREAT`: `boolean` -> `number` [^boolean-to-number]
- `RENAMENX`: `boolean` -> `number` [^boolean-to-number]
- `HSCAN`: `tuples` has been renamed to `entries`
- `PFADD`: `boolean` -> `number` [^boolean-to-number]
[^enum-to-constants]:
TODO
[^boolean-to-number]
TODO
## Command Options
in v4, command options are passed as a first optional argument:
```javascript
await client.get('key'); // `string | null`
await client.get(client.commandOptions({ returnBuffers: true }), 'key'); // `Buffer | null`
```
which has a couple of flaws:
1. The arguments types is checked in runtime, which hit performance.
2. Makes code suggestions less readable/usable, due to "function overloading".
3. Overall makes the "user code" not very readable.
### The new API
With the new API instead of passing the options directrly to the commands, we use a "proxy client" to store the options:
```javascript
await client.get('key'); // `string | null`
const proxyClient = client.withCommandOptions({
flags: {
[TYPES.BLOB_STRING]: Buffer
}
});
await proxyClient.get('key'); // `Buffer | null`
```
`withCommandOptions` can be used to override all the command options, without reusing any of the existing ones.
On top of that, these functions can be used to override a specific option:
- `withFlags` - override `flags` only.
- `asap` - override `asap` to `true`.
- `isolated` - override `isolated` to `true`.
## Quit VS Disconnect
close
quit
disconnect
TODO

30
md/v5-new-features.md Normal file
View File

@@ -0,0 +1,30 @@
# RESP3 Support
```javascript
client.hGetAll('key'); // Record<string, string>
client.withFlags({
[TYPES.MAP]: Map
}).hGetAll('key'); // Map<string, string>
client.withFlags({
[TYPES.MAP]: Map,
[TYPES.BLOB_STRING]: Buffer
}).hGetAll('key'); // Map<string, Buffer>
```
# `Multi.exec<'typed'>`
```javascript
client.multi()
.ping()
.exec(); // Array<ReplyUnion>
client.multi()
.ping()
.exec<'typed'>(); // [string]
```
# Request & Reply Policies
see [here](../docs/clustering.md#command-routing).