Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(ts): xtrim threshold accepts string #2828

Draft
wants to merge 32 commits into
base: v5
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
bfa803f
Fix race condition when slots are re-calculated (#2731)
jjsimps May 16, 2024
d7f7f79
Release [email protected]
leibale May 16, 2024
1a3ac1e
upgrade @redis/client
leibale May 16, 2024
d5518e0
Release [email protected]
leibale May 16, 2024
fcf4119
upgrade @redis/client
leibale May 16, 2024
d5355d4
Release [email protected]
leibale May 16, 2024
4ac97ee
fix createCluster - copy `options.defaults.socket` before modifying i…
soccermax Jul 2, 2024
60c1c46
Release [email protected]
leibale Jul 2, 2024
b4c1e59
Upgrade @redis/client
leibale Jul 2, 2024
72345fe
Release [email protected]
leibale Jul 2, 2024
b4df2b2
add support for all hash field expiration commands (#2787)
sjpotter Jul 10, 2024
7d43a97
add CLIENT KILL maxAge support (v4) (#2761)
sjpotter Jul 10, 2024
a1bee1c
add geoshape support (#2788)
sjpotter Jul 10, 2024
5576a0d
CAE-193: add "IGNORE" options to time series commands (for v4 branch)…
sjpotter Jul 10, 2024
64fca37
Support the NOVALUES option of HSCAN (#2711)
gerzse Jul 14, 2024
0e7e2e6
add missing fields support to schema (v4) (#2789)
sjpotter Jul 17, 2024
d09aaa3
small internal tweak for maxage per discussion w/ leibele (#2803)
sjpotter Jul 23, 2024
b884e13
don't expand/copy rawValues, return it directly. (#2800)
sjpotter Jul 23, 2024
6f79b49
updated per discussion w/ leibele (#2804)
sjpotter Jul 24, 2024
54b3e17
add addscores to aggregate search command (#2799)
sjpotter Jul 29, 2024
dc3be85
add 7.4-rc2 to github action test suite (#2793)
sjpotter Jul 29, 2024
179b9e0
fix: json.mget should be readonly (#2807) (#2808)
marcoreni Jul 29, 2024
840ec57
small refactor per discussion with leibele (#2801)
sjpotter Jul 29, 2024
3973fa2
Release [email protected]
leibale Jul 29, 2024
49ef273
Update tests.yml
leibale Jul 29, 2024
18ccc28
fix hash expiration tests
leibale Jul 29, 2024
fff7b00
Release [email protected]
leibale Jul 29, 2024
268ceda
Release [email protected]
leibale Jul 29, 2024
b493afa
Release [email protected]
leibale Jul 29, 2024
878fb69
upgrade deps
leibale Jul 29, 2024
2fc79bd
Release [email protected]
leibale Jul 29, 2024
a42b7fb
fix(ts): xtrim threshold accepts string
Eomm Sep 5, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
fail-fast: false
matrix:
node-version: ['18', '20']
redis-version: ['5', '6.0', '6.2', '7.0', '7.2']
redis-version: ['5', '6.0', '6.2', '7.0', '7.2', '7.4-rc2']
steps:
- uses: actions/checkout@v4
with:
Expand Down
20 changes: 10 additions & 10 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "redis",
"description": "A modern, high performance Redis client",
"version": "4.6.13",
"version": "4.7.0",
"license": "MIT",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
Expand All @@ -24,11 +24,11 @@
},
"dependencies": {
"@redis/bloom": "1.2.0",
"@redis/client": "1.5.14",
"@redis/client": "1.6.0",
"@redis/graph": "1.1.1",
"@redis/json": "1.0.6",
"@redis/search": "1.1.6",
"@redis/time-series": "1.0.5"
"@redis/json": "1.0.7",
"@redis/search": "1.2.0",
"@redis/time-series": "1.1.0"
},
"devDependencies": {
"@tsconfig/node14": "^14.1.0",
Expand Down
25 changes: 25 additions & 0 deletions packages/client/lib/client/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,31 @@ describe('Client', () => {
assert.deepEqual(hash, results);
}, GLOBAL.SERVERS.OPEN);

testUtils.testWithClient('hScanNoValuesIterator', async client => {
const hash: Record<string, string> = {};
const expectedKeys: Array<string> = [];
for (let i = 0; i < 100; i++) {
hash[i.toString()] = i.toString();
expectedKeys.push(i.toString());
}

await client.hSet('key', hash);

const keys: Array<string> = [];
for await (const key of client.hScanNoValuesIterator('key')) {
keys.push(key);
}

function sort(a: string, b: string) {
return Number(a) - Number(b);
}

assert.deepEqual(keys.sort(sort), expectedKeys);
}, {
...GLOBAL.SERVERS.OPEN,
minimumDockerVersion: [7, 4]
});

testUtils.testWithClient('sScanIterator', async client => {
const members = new Set<string>();
for (let i = 0; i < 100; i++) {
Expand Down
13 changes: 12 additions & 1 deletion packages/client/lib/client/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import COMMANDS from './commands';
import { RedisCommand, RedisCommandArguments, RedisCommandRawReply, RedisCommandReply, RedisFunctions, RedisModules, RedisExtensions, RedisScript, RedisScripts, RedisCommandSignature, ConvertArgumentType, RedisFunction, ExcludeMappedString, RedisCommands } from '../commands';
import { RedisCommand, RedisCommandArgument, RedisCommandArguments, RedisCommandRawReply, RedisCommandReply, RedisFunctions, RedisModules, RedisExtensions, RedisScript, RedisScripts, RedisCommandSignature, ConvertArgumentType, RedisFunction, ExcludeMappedString, RedisCommands } from '../commands';
import RedisSocket, { RedisSocketOptions, RedisTlsSocketOptions } from './socket';
import RedisCommandsQueue, { QueueCommandOptions } from './commands-queue';
import RedisClientMultiCommand, { RedisClientMultiCommandType } from './multi-command';
Expand Down Expand Up @@ -820,6 +820,17 @@ export default class RedisClient<
} while (cursor !== 0);
}

async* hScanNoValuesIterator(key: string, options?: ScanOptions): AsyncIterable<ConvertArgumentType<RedisCommandArgument, string>> {
let cursor = 0;
do {
const reply = await (this as any).hScanNoValues(key, cursor, options);
cursor = reply.cursor;
for (const k of reply.keys) {
yield k;
}
} while (cursor !== 0);
}

async* sScanIterator(key: string, options?: ScanOptions): AsyncIterable<string> {
let cursor = 0;
do {
Expand Down
8 changes: 4 additions & 4 deletions packages/client/lib/cluster/cluster-slots.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,13 +158,13 @@ export default class RedisClusterSlots<
}

async #discover(rootNode?: RedisClusterClientOptions) {
this.#resetSlots();
const addressesInUse = new Set<string>();

try {
const shards = await this.#getShards(rootNode),
promises: Array<Promise<unknown>> = [],
eagerConnect = this.#options.minimizeConnections !== true;
this.#resetSlots();
for (const { from, to, master, replicas } of shards) {
const shard: Shard<M, F, S> = {
master: this.#initiateSlotNode(master, false, eagerConnect, addressesInUse, promises)
Expand Down Expand Up @@ -269,10 +269,10 @@ export default class RedisClusterSlots<
if (this.#options.defaults) {
let socket;
if (this.#options.defaults.socket) {
socket = options?.socket ? {
socket = {
...this.#options.defaults.socket,
...options.socket
} : this.#options.defaults.socket;
...options?.socket
};
} else {
socket = options?.socket;
}
Expand Down
30 changes: 30 additions & 0 deletions packages/client/lib/cluster/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,20 +53,30 @@ import * as GETRANGE from '../commands/GETRANGE';
import * as GETSET from '../commands/GETSET';
import * as HDEL from '../commands/HDEL';
import * as HEXISTS from '../commands/HEXISTS';
import * as HEXPIRE from '../commands/HEXPIRE';
import * as HEXPIREAT from '../commands/HEXPIREAT';
import * as HEXPIRETIME from '../commands/HEXPIRETIME';
import * as HGET from '../commands/HGET';
import * as HGETALL from '../commands/HGETALL';
import * as HINCRBY from '../commands/HINCRBY';
import * as HINCRBYFLOAT from '../commands/HINCRBYFLOAT';
import * as HKEYS from '../commands/HKEYS';
import * as HLEN from '../commands/HLEN';
import * as HMGET from '../commands/HMGET';
import * as HPERSIST from '../commands/HPERSIST';
import * as HPEXPIRE from '../commands/HPEXPIRE';
import * as HPEXPIREAT from '../commands/HPEXPIREAT';
import * as HPEXPIRETIME from '../commands/HPEXPIRETIME';
import * as HPTTL from '../commands/HPTTL';
import * as HRANDFIELD_COUNT_WITHVALUES from '../commands/HRANDFIELD_COUNT_WITHVALUES';
import * as HRANDFIELD_COUNT from '../commands/HRANDFIELD_COUNT';
import * as HRANDFIELD from '../commands/HRANDFIELD';
import * as HSCAN from '../commands/HSCAN';
import * as HSCAN_NOVALUES from '../commands/HSCAN_NOVALUES';
import * as HSET from '../commands/HSET';
import * as HSETNX from '../commands/HSETNX';
import * as HSTRLEN from '../commands/HSTRLEN';
import * as HTTL from '../commands/HTTL';
import * as HVALS from '../commands/HVALS';
import * as INCR from '../commands/INCR';
import * as INCRBY from '../commands/INCRBY';
Expand Down Expand Up @@ -321,6 +331,12 @@ export default {
hDel: HDEL,
HEXISTS,
hExists: HEXISTS,
HEXPIRE,
hExpire: HEXPIRE,
HEXPIREAT,
hExpireAt: HEXPIREAT,
HEXPIRETIME,
hExpireTime: HEXPIRETIME,
HGET,
hGet: HGET,
HGETALL,
Expand All @@ -335,6 +351,16 @@ export default {
hLen: HLEN,
HMGET,
hmGet: HMGET,
HPERSIST,
hPersist: HPERSIST,
HPEXPIRE,
hpExpire: HPEXPIRE,
HPEXPIREAT,
hpExpireAt: HPEXPIREAT,
HPEXPIRETIME,
hpExpireTime: HPEXPIRETIME,
HPTTL,
hpTTL: HPTTL,
HRANDFIELD_COUNT_WITHVALUES,
hRandFieldCountWithValues: HRANDFIELD_COUNT_WITHVALUES,
HRANDFIELD_COUNT,
Expand All @@ -343,12 +369,16 @@ export default {
hRandField: HRANDFIELD,
HSCAN,
hScan: HSCAN,
HSCAN_NOVALUES,
hScanNoValues: HSCAN_NOVALUES,
HSET,
hSet: HSET,
HSETNX,
hSetNX: HSETNX,
HSTRLEN,
hStrLen: HSTRLEN,
HTTL,
hTTL: HTTL,
HVALS,
hVals: HVALS,
INCR,
Expand Down
10 changes: 10 additions & 0 deletions packages/client/lib/commands/CLIENT_KILL.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,16 @@ describe('CLIENT KILL', () => {
);
});

it('MAXAGE', () => {
assert.deepEqual(
transformArguments({
filter: ClientKillFilters.MAXAGE,
maxAge: 10
}),
['CLIENT', 'KILL', 'MAXAGE', '10']
);
});

describe('SKIP_ME', () => {
it('undefined', () => {
assert.deepEqual(
Expand Down
13 changes: 11 additions & 2 deletions packages/client/lib/commands/CLIENT_KILL.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ export enum ClientKillFilters {
ID = 'ID',
TYPE = 'TYPE',
USER = 'USER',
SKIP_ME = 'SKIPME'
SKIP_ME = 'SKIPME',
MAXAGE = 'MAXAGE'
}

interface KillFilter<T extends ClientKillFilters> {
Expand Down Expand Up @@ -37,7 +38,11 @@ type KillSkipMe = ClientKillFilters.SKIP_ME | (KillFilter<ClientKillFilters.SKIP
skipMe: boolean;
});

type KillFilters = KillAddress | KillLocalAddress | KillId | KillType | KillUser | KillSkipMe;
interface KillMaxAge extends KillFilter<ClientKillFilters.MAXAGE> {
maxAge: number;
}

type KillFilters = KillAddress | KillLocalAddress | KillId | KillType | KillUser | KillSkipMe | KillMaxAge;

export function transformArguments(filters: KillFilters | Array<KillFilters>): RedisCommandArguments {
const args = ['CLIENT', 'KILL'];
Expand Down Expand Up @@ -89,6 +94,10 @@ function pushFilter(args: RedisCommandArguments, filter: KillFilters): void {
case ClientKillFilters.SKIP_ME:
args.push(filter.skipMe ? 'yes' : 'no');
break;

case ClientKillFilters.MAXAGE:
args.push(filter.maxAge.toString());
break;
}
}

Expand Down
40 changes: 40 additions & 0 deletions packages/client/lib/commands/HEXPIRE.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { strict as assert } from 'node:assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './HEXPIRE';
import { HASH_EXPIRATION_TIME } from './HEXPIRETIME';

describe('HEXPIRE', () => {
testUtils.isVersionGreaterThanHook([7, 4]);

describe('transformArguments', () => {
it('string', () => {
assert.deepEqual(
transformArguments('key', 'field', 1),
['HEXPIRE', 'key', '1', 'FIELDS', '1', 'field']
);
});

it('array', () => {
assert.deepEqual(
transformArguments('key', ['field1', 'field2'], 1),
['HEXPIRE', 'key', '1', 'FIELDS', '2', 'field1', 'field2']
);
});

it('with set option', () => {
assert.deepEqual(
transformArguments('key', ['field1'], 1, 'NX'),
['HEXPIRE', 'key', '1', 'NX', 'FIELDS', '1', 'field1']
);
});
});

testUtils.testWithClient('hexpire', async client => {
assert.deepEqual(
await client.hExpire('key', ['field1'], 0),
[HASH_EXPIRATION_TIME.FIELD_NOT_EXISTS]
);
}, {
...GLOBAL.SERVERS.OPEN
});
});
Loading