You've already forked node-redis
mirror of
https://github.com/redis/node-redis.git
synced 2025-08-09 00:22:08 +03:00
upgrade dependencies, update README
This commit is contained in:
176
README.md
176
README.md
@@ -35,17 +35,17 @@ npm install redis@next
|
||||
### Basic Example
|
||||
|
||||
```typescript
|
||||
import { createClient } from 'redis';
|
||||
import { createClient } from "redis";
|
||||
|
||||
(async () => {
|
||||
const client = createClient();
|
||||
const client = createClient();
|
||||
|
||||
client.on('error', (err) => console.log('Redis Client Error', err));
|
||||
client.on("error", (err) => console.log("Redis Client Error", err));
|
||||
|
||||
await client.connect();
|
||||
await client.connect();
|
||||
|
||||
await client.set('key', 'value');
|
||||
const value = await client.get('key');
|
||||
await client.set("key", "value");
|
||||
const value = await client.get("key");
|
||||
})();
|
||||
```
|
||||
|
||||
@@ -53,9 +53,9 @@ The above code connects to localhost on port 6379. To connect to a different hos
|
||||
|
||||
```typescript
|
||||
createClient({
|
||||
socket: {
|
||||
url: 'redis://alice:foobared@awesome.redis.server:6380'
|
||||
}
|
||||
socket: {
|
||||
url: "redis://alice:foobared@awesome.redis.server:6380",
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
@@ -67,28 +67,28 @@ There is built-in support for all of the [out-of-the-box Redis commands](https:/
|
||||
|
||||
```typescript
|
||||
// raw Redis commands
|
||||
await client.HSET('key', 'field', 'value');
|
||||
await client.HGETALL('key');
|
||||
await client.HSET("key", "field", "value");
|
||||
await client.HGETALL("key");
|
||||
|
||||
// friendly JavaScript commands
|
||||
await client.hSet('key', 'field', 'value');
|
||||
await client.hGetAll('key');
|
||||
await client.hSet("key", "field", "value");
|
||||
await client.hGetAll("key");
|
||||
```
|
||||
|
||||
Modifiers to commands are specified using a JavaScript object:
|
||||
|
||||
```typescript
|
||||
await client.set('key', 'value', {
|
||||
EX: 10,
|
||||
NX: true
|
||||
await client.set("key", "value", {
|
||||
EX: 10,
|
||||
NX: true,
|
||||
});
|
||||
```
|
||||
|
||||
Replies will be transformed into useful data structures:
|
||||
|
||||
```typescript
|
||||
await client.hGetAll('key'); // { field1: 'value1', field2: 'value2' }
|
||||
await client.hVals('key'); // ['value1', 'value2']
|
||||
await client.hGetAll("key"); // { field1: 'value1', field2: 'value2' }
|
||||
await client.hVals("key"); // ['value1', 'value2']
|
||||
```
|
||||
|
||||
### Unsupported Redis Commands
|
||||
@@ -96,9 +96,9 @@ await client.hVals('key'); // ['value1', 'value2']
|
||||
If you want to run commands and/or use arguments that Node Redis doesn't know about (yet!) use `.sendCommand()`:
|
||||
|
||||
```typescript
|
||||
await client.sendCommand(['SET', 'key', 'value', 'NX']); // 'OK'
|
||||
await client.sendCommand(["SET", "key", "value", "NX"]); // 'OK'
|
||||
|
||||
await client.sendCommand(['HGETALL', 'key']); // ['key1', 'field1', 'key2', 'field2']
|
||||
await client.sendCommand(["HGETALL", "key"]); // ['key1', 'field1', 'key2', 'field2']
|
||||
```
|
||||
|
||||
### Transactions (Multi/Exec)
|
||||
@@ -106,12 +106,13 @@ await client.sendCommand(['HGETALL', 'key']); // ['key1', 'field1', 'key2', 'fie
|
||||
Start a [transaction](https://redis.io/topics/transactions) by calling `.multi()`, then chaining your commands. When you're done, call `.exec()` and you'll get an array back with your results:
|
||||
|
||||
```typescript
|
||||
await client.set('another-key', 'another-value');
|
||||
await client.set("another-key", "another-value");
|
||||
|
||||
const [ setKeyReply, otherKeyValue ] = await client.multi()
|
||||
.set('key', 'value')
|
||||
.get('another-key')
|
||||
.exec(); // ['OK', 'another-value']
|
||||
const [setKeyReply, otherKeyValue] = await client
|
||||
.multi()
|
||||
.set("key", "value")
|
||||
.get("another-key")
|
||||
.exec(); // ['OK', 'another-value']
|
||||
```
|
||||
|
||||
You can also [watch](https://redis.io/topics/transactions#optimistic-locking-using-check-and-set) keys by calling `.watch()`. Your transaction will abort if any of the watched keys change.
|
||||
@@ -125,14 +126,11 @@ Any command can be run on a new connection by specifying the `isolated` option.
|
||||
This pattern works especially well for blocking commands—such as `BLPOP` and `BLMOVE`:
|
||||
|
||||
```typescript
|
||||
import { commandOptions } from 'redis';
|
||||
import { commandOptions } from "redis";
|
||||
|
||||
const blPopPromise = client.blPop(
|
||||
commandOptions({ isolated: true }),
|
||||
'key'
|
||||
);
|
||||
const blPopPromise = client.blPop(commandOptions({ isolated: true }), "key");
|
||||
|
||||
await client.lPush('key', ['1', '2']);
|
||||
await client.lPush("key", ["1", "2"]);
|
||||
|
||||
await blPopPromise; // '2'
|
||||
```
|
||||
@@ -152,23 +150,23 @@ await subscriber.connect();
|
||||
Once you have one, simply subscribe and unsubscribe as needed:
|
||||
|
||||
```typescript
|
||||
await subscriber.subscribe('channel', message => {
|
||||
console.log(message); // 'message'
|
||||
await subscriber.subscribe("channel", (message) => {
|
||||
console.log(message); // 'message'
|
||||
});
|
||||
|
||||
await subscriber.pSubscribe('channe*', (message, channel) => {
|
||||
console.log(message, channel); // 'message', 'channel'
|
||||
await subscriber.pSubscribe("channe*", (message, channel) => {
|
||||
console.log(message, channel); // 'message', 'channel'
|
||||
});
|
||||
|
||||
await subscriber.unsubscribe('channel');
|
||||
await subscriber.unsubscribe("channel");
|
||||
|
||||
await subscriber.pUnsubscribe('channe*');
|
||||
await subscriber.pUnsubscribe("channe*");
|
||||
```
|
||||
|
||||
Publish a message on a channel:
|
||||
|
||||
```typescript
|
||||
await publisher.publish('channel', 'message');
|
||||
await publisher.publish("channel", "message");
|
||||
```
|
||||
|
||||
### Scan Iterator
|
||||
@@ -177,26 +175,29 @@ await publisher.publish('channel', 'message');
|
||||
|
||||
```typescript
|
||||
for await (const key of client.scanIterator()) {
|
||||
// use the key!
|
||||
await client.get(key);
|
||||
// use the key!
|
||||
await client.get(key);
|
||||
}
|
||||
```
|
||||
|
||||
This works with `HSCAN`, `SSCAN`, and `ZSCAN` too:
|
||||
|
||||
```typescript
|
||||
for await (const member of client.hScanIterator('hash')) {}
|
||||
for await (const { field, value } of client.sScanIterator('set')) {}
|
||||
for await (const { member, score } of client.zScanIterator('sorted-set')) {}
|
||||
for await (const member of client.hScanIterator("hash")) {
|
||||
}
|
||||
for await (const { field, value } of client.sScanIterator("set")) {
|
||||
}
|
||||
for await (const { member, score } of client.zScanIterator("sorted-set")) {
|
||||
}
|
||||
```
|
||||
|
||||
You can override the default options by providing a configuration object:
|
||||
|
||||
```typescript
|
||||
client.scanIterator({
|
||||
TYPE: 'string', // `SCAN` only
|
||||
MATCH: 'patter*',
|
||||
COUNT: 100
|
||||
TYPE: "string", // `SCAN` only
|
||||
MATCH: "patter*",
|
||||
COUNT: 100,
|
||||
});
|
||||
```
|
||||
|
||||
@@ -205,30 +206,29 @@ client.scanIterator({
|
||||
Define new functions using [Lua scripts](https://redis.io/commands/eval) which execute on the Redis server:
|
||||
|
||||
```typescript
|
||||
import { createClient, defineScript } from 'redis';
|
||||
import { createClient, defineScript } from "redis";
|
||||
|
||||
(async () => {
|
||||
const client = createClient({
|
||||
scripts: {
|
||||
add: defineScript({
|
||||
NUMBER_OF_KEYS: 1,
|
||||
SCRIPT:
|
||||
'local val = redis.pcall("GET", KEYS[1]);' +
|
||||
'return val + ARGV[1];',
|
||||
transformArguments(key: string, toAdd: number): Array<string> {
|
||||
return [key, number.toString()];
|
||||
},
|
||||
transformReply(reply: number): number {
|
||||
return reply;
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
const client = createClient({
|
||||
scripts: {
|
||||
add: defineScript({
|
||||
NUMBER_OF_KEYS: 1,
|
||||
SCRIPT:
|
||||
'local val = redis.pcall("GET", KEYS[1]);' + "return val + ARGV[1];",
|
||||
transformArguments(key: string, toAdd: number): Array<string> {
|
||||
return [key, number.toString()];
|
||||
},
|
||||
transformReply(reply: number): number {
|
||||
return reply;
|
||||
},
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
await client.connect();
|
||||
await client.connect();
|
||||
|
||||
await client.set('key', '1');
|
||||
await client.add('key', 2); // 3
|
||||
await client.set("key", "1");
|
||||
await client.add("key", 2); // 3
|
||||
})();
|
||||
```
|
||||
|
||||
@@ -237,25 +237,28 @@ import { createClient, defineScript } from 'redis';
|
||||
Connecting to a cluster is a bit different. Create the client by specifying some (or all) of the nodes in your cluster and then use it like a non-clustered client:
|
||||
|
||||
```typescript
|
||||
import { createCluster } from 'redis';
|
||||
import { createCluster } from "redis";
|
||||
|
||||
(async () => {
|
||||
const cluster = createCluster({
|
||||
rootNodes: [{
|
||||
host: '10.0.0.1',
|
||||
port: 30001
|
||||
}, {
|
||||
host: '10.0.0.2',
|
||||
port: 30002
|
||||
}]
|
||||
});
|
||||
const cluster = createCluster({
|
||||
rootNodes: [
|
||||
{
|
||||
host: "10.0.0.1",
|
||||
port: 30001,
|
||||
},
|
||||
{
|
||||
host: "10.0.0.2",
|
||||
port: 30002,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
cluster.on('error', (err) => console.log('Redis Cluster Error', err));
|
||||
cluster.on("error", (err) => console.log("Redis Cluster Error", err));
|
||||
|
||||
await cluster.connect();
|
||||
await cluster.connect();
|
||||
|
||||
await cluster.set('key', 'value');
|
||||
const value = await cluster.get('key');
|
||||
await cluster.set("key", "value");
|
||||
const value = await cluster.get("key");
|
||||
})();
|
||||
```
|
||||
|
||||
@@ -264,16 +267,16 @@ import { createCluster } from 'redis';
|
||||
Node Redis will automatically pipeline requests that are made during the same "tick".
|
||||
|
||||
```typescript
|
||||
client.set('Tm9kZSBSZWRpcw==', 'users:1');
|
||||
client.sAdd('users:1:tokens', 'Tm9kZSBSZWRpcw==');
|
||||
client.set("Tm9kZSBSZWRpcw==", "users:1");
|
||||
client.sAdd("users:1:tokens", "Tm9kZSBSZWRpcw==");
|
||||
```
|
||||
|
||||
Of course, if you don't do something with your Promises you're certain to get [unhandled Promise exceptions](https://nodejs.org/api/process.html#process_event_unhandledrejection). To take advantage of auto-pipelining and handle your Promises, use `Promise.all()`.
|
||||
|
||||
```typescript
|
||||
await Promise.all([
|
||||
client.set('Tm9kZSBSZWRpcw==', 'users:1'),
|
||||
client.sAdd('users:1:tokens', 'Tm9kZSBSZWRpcw==')
|
||||
client.set("Tm9kZSBSZWRpcw==", "users:1"),
|
||||
client.sAdd("users:1:tokens", "Tm9kZSBSZWRpcw=="),
|
||||
]);
|
||||
```
|
||||
|
||||
@@ -283,8 +286,9 @@ If you'd like to contribute, check out the [contributing guide](CONTRIBUTING.md)
|
||||
|
||||
Thank you to all the people who already contributed to Node Redis!
|
||||
|
||||
<a href="https://github.com/NodeRedis/node-redis/graphs/contributors"><img src="https://opencollective.com/node-redis/contributors.svg?width=1012" /></a>
|
||||
|
||||
<a href="https://github.com/NodeRedis/node-redis/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=NodeRedis/node-redis"/>
|
||||
</a>
|
||||
## License
|
||||
|
||||
This repository is licensed under the "MIT" license. See [LICENSE](LICENSE).
|
||||
|
856
package-lock.json
generated
856
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
10
package.json
10
package.json
@@ -35,7 +35,7 @@
|
||||
"devDependencies": {
|
||||
"@istanbuljs/nyc-config-typescript": "^1.0.1",
|
||||
"@types/mocha": "^9.0.0",
|
||||
"@types/node": "^16.7.10",
|
||||
"@types/node": "^16.9.4",
|
||||
"@types/sinon": "^10.0.2",
|
||||
"@types/which": "^2.0.1",
|
||||
"@types/yallist": "^4.0.1",
|
||||
@@ -43,12 +43,12 @@
|
||||
"nyc": "^15.1.0",
|
||||
"release-it": "^14.11.5",
|
||||
"sinon": "^11.1.2",
|
||||
"source-map-support": "^0.5.19",
|
||||
"source-map-support": "^0.5.20",
|
||||
"ts-node": "^10.2.1",
|
||||
"typedoc": "^0.21.9",
|
||||
"typedoc": "^0.22.4",
|
||||
"typedoc-github-wiki-theme": "^0.5.1",
|
||||
"typedoc-plugin-markdown": "^3.10.4",
|
||||
"typescript": "^4.4.2",
|
||||
"typedoc-plugin-markdown": "^3.11.0",
|
||||
"typescript": "^4.4.3",
|
||||
"which": "^2.0.2"
|
||||
},
|
||||
"engines": {
|
||||
|
Reference in New Issue
Block a user