1
0
mirror of https://github.com/redis/node-redis.git synced 2025-08-07 13:22:56 +03:00

Update README.MD (#2924)

* Update README.MD

* docs: update programmability.md examples

+ add Programmability section to README and

* fix imports according to the new v5 exports

* more v5 docs updates

---------

Co-authored-by: Nikolay Karadzhov <nkaradzhov89@gmail.com>
This commit is contained in:
Bobby I.
2025-04-30 16:28:22 +03:00
committed by GitHub
parent 9459660d96
commit 49d6b2d465
5 changed files with 341 additions and 30 deletions

View File

@@ -23,7 +23,7 @@ By default, each type is mapped to the first option in the lists below. To chang
- Double (`,`) => `number | string`
- Simple String (`+`) => `string | Buffer`
- Blob String (`$`) => `string | Buffer`
- Verbatim String (`=`) => `string | Buffer | VerbatimString` (TODO: `VerbatimString` typedoc link)
- Verbatim String (`=`) => `string | Buffer | VerbatimString`
- Simple Error (`-`) => `ErrorReply`
- Blob Error (`!`) => `ErrorReply`
- Array (`*`) => `Array`

View File

@@ -25,16 +25,22 @@ FUNCTION LOAD "#!lua name=library\nredis.register_function{function_name='add',
Load the prior redis function on the _redis server_ before running the example below.
```typescript
import { createClient } from 'redis';
import { CommandParser } from '@redis/client/lib/client/parser';
import { NumberReply } from '@redis/client/lib/RESP/types';
import { createClient, RedisArgument } from 'redis';
const client = createClient({
functions: {
library: {
add: {
NUMBER_OF_KEYS: 1,
FIRST_KEY_INDEX: 1,
transformArguments(key: string, toAdd: number): Array<string> {
return [key, toAdd.toString()];
parseCommand(
parser: CommandParser,
key: RedisArgument,
toAdd: RedisArgument
) {
parser.pushKey(key)
parser.push(toAdd)
},
transformReply: undefined as unknown as () => NumberReply
}
@@ -43,9 +49,8 @@ const client = createClient({
});
await client.connect();
await client.set('key', '1');
await client.library.add('key', 2); // 3
await client.library.add('key', '2'); // 3
```
## [Lua Scripts](https://redis.io/docs/manual/programmability/eval-intro/)
@@ -53,7 +58,9 @@ await client.library.add('key', 2); // 3
The following is an end-to-end example of the prior concept.
```typescript
import { createClient, defineScript, NumberReply } from 'redis';
import { CommandParser } from '@redis/client/lib/client/parser';
import { NumberReply } from '@redis/client/lib/RESP/types';
import { createClient, defineScript, RedisArgument } from 'redis';
const client = createClient({
scripts: {
@@ -61,8 +68,13 @@ const client = createClient({
SCRIPT: 'return redis.call("GET", KEYS[1]) + ARGV[1];',
NUMBER_OF_KEYS: 1,
FIRST_KEY_INDEX: 1,
transformArguments(key: string, toAdd: number): Array<string> {
return [key, toAdd.toString()];
parseCommand(
parser: CommandParser,
key: RedisArgument,
toAdd: RedisArgument
) {
parser.pushKey(key)
parser.push(toAdd)
},
transformReply: undefined as unknown as () => NumberReply
})
@@ -70,7 +82,6 @@ const client = createClient({
});
await client.connect();
await client.set('key', '1');
await client.add('key', 2); // 3
await client.add('key', '2'); // 3
```

View File

@@ -234,12 +234,12 @@ In v5, any unwritten commands (in the same pipeline) will be discarded.
### Time Series
- `TS.ADD`: `boolean` -> `number` [^boolean-to-number]
- `TS.[M][REV]RANGE`: `enum TimeSeriesBucketTimestamp` -> `const TIME_SERIES_BUCKET_TIMESTAMP` [^enum-to-constants], `enum TimeSeriesReducers` -> `const TIME_SERIES_REDUCERS` [^enum-to-constants], the `ALIGN` argument has been moved into `AGGREGRATION`
- `TS.[M][REV]RANGE`: the `ALIGN` argument has been moved into `AGGREGATION`
- `TS.SYNUPDATE`: `Array<string | Array<string>>` -> `Record<string, Array<string>>`
- `TS.M[REV]RANGE[_WITHLABELS]`, `TS.MGET[_WITHLABELS]`: TODO
[^enum-to-constants]: TODO
- `TimeSeriesDuplicatePolicies` -> `TIME_SERIES_DUPLICATE_POLICIES` [^enum-to-constants]
- `TimeSeriesEncoding` -> `TIME_SERIES_ENCODING` [^enum-to-constants]
- `TimeSeriesAggregationType` -> `TIME_SERIES_AGGREGATION_TYPE` [^enum-to-constants]
- `TimeSeriesReducers` -> `TIME_SERIES_REDUCERS` [^enum-to-constants]
- `TimeSeriesBucketTimestamp` -> `TIME_SERIES_BUCKET_TIMESTAMP` [^enum-to-constants]
[^map-keys]: To avoid unnecessary transformations and confusion, map keys will not be transformed to "js friendly" names (i.e. `number-of-keys` will not be renamed to `numberOfKeys`). See [here](https://github.com/redis/node-redis/discussions/2506).
[^future-proofing]: TODO

View File

@@ -1,30 +1,83 @@
# RESP3 Support
TODO
Node Redis v5 adds support for [RESP3](https://github.com/redis/redis-specifications/blob/master/protocol/RESP3.md), the new Redis serialization protocol. RESP3 offers richer data types and improved type handling compared to RESP2.
To use RESP3, specify it when creating your client:
```javascript
import { createClient } from 'redis';
const client = createClient({
RESP: 3
});
```
## Type Mapping
With RESP3, you can leverage the protocol's richer type system. You can customize how different Redis types are represented in JavaScript using type mapping:
```javascript
// by default
import { createClient, RESP_TYPES } from 'redis';
// By default
await client.hGetAll('key'); // Record<string, string>
// Use Map instead of plain object
await client.withTypeMapping({
[TYPES.MAP]: Map
[RESP_TYPES.MAP]: Map
}).hGetAll('key'); // Map<string, string>
// Use both Map and Buffer
await client.withTypeMapping({
[TYPES.MAP]: Map,
[TYPES.BLOB_STRING]: Buffer
[RESP_TYPES.MAP]: Map,
[RESP_TYPES.BLOB_STRING]: Buffer
}).hGetAll('key'); // Map<string, Buffer>
```
This replaces the previous approach of using `commandOptions({ returnBuffers: true })` in v4.
## PubSub in RESP3
RESP3 uses a different mechanism for handling Pub/Sub messages. Instead of modifying the `onReply` handler as in RESP2, RESP3 provides a dedicated `onPush` handler. When using RESP3, the client automatically uses this more efficient push notification system.
## Known Limitations
### Unstable Module Commands
Some Redis module commands have unstable RESP3 transformations. These commands will throw an error when used with RESP3 unless you explicitly opt in to using them by setting `unstableResp3: true` in your client configuration:
```javascript
const client = createClient({
RESP: 3,
unstableResp3: true
});
```
The following commands have unstable RESP3 implementations:
1. **Stream Commands**:
- `XREAD` and `XREADGROUP` - The response format differs between RESP2 and RESP3
2. **Search Commands (RediSearch)**:
- `FT.AGGREGATE`
- `FT.AGGREGATE_WITHCURSOR`
- `FT.CURSOR_READ`
- `FT.INFO`
- `FT.PROFILE_AGGREGATE`
- `FT.PROFILE_SEARCH`
- `FT.SEARCH`
- `FT.SEARCH_NOCONTENT`
- `FT.SPELLCHECK`
3. **Time Series Commands**:
- `TS.INFO`
- `TS.INFO_DEBUG`
If you need to use these commands with RESP3, be aware that the response format might change in future versions.
# Sentinel Support
[TODO](./sentinel.md)
[Sentinel](./sentinel.md)
# `multi.exec<'typed'>` / `multi.execTyped`