You've already forked node-redis
mirror of
https://github.com/redis/node-redis.git
synced 2025-08-06 02:15:48 +03:00
bloom module
This commit is contained in:
2
.github/workflows/tests.yml
vendored
2
.github/workflows/tests.yml
vendored
@@ -34,7 +34,7 @@ jobs:
|
|||||||
- name: Build
|
- name: Build
|
||||||
run: npm run build -- ./packages/client ./packages/test-utils/
|
run: npm run build -- ./packages/client ./packages/test-utils/
|
||||||
- name: Run Tests
|
- name: Run Tests
|
||||||
run: npm run test -w ./packages/client -- --forbid-only --redis-version=${{ matrix.redis-version }}
|
run: npm run test -w ./packages/client -- --forbid-only --redis-version=${{ matrix.redis-version }} && npm run test -w ./packages/bloom -- --forbid-only
|
||||||
- name: Upload to Codecov
|
- name: Upload to Codecov
|
||||||
run: |
|
run: |
|
||||||
curl https://keybase.io/codecovsecurity/pgp_keys.asc | gpg --no-default-keyring --keyring trustedkeys.gpg --import
|
curl https://keybase.io/codecovsecurity/pgp_keys.asc | gpg --no-default-keyring --keyring trustedkeys.gpg --import
|
||||||
|
@@ -174,6 +174,7 @@ Some command arguments/replies have changed to align more closely to data types
|
|||||||
- `XINFO GROUPS`: `lastDeliveredId` -> `last-delivered-id` [^map-keys]
|
- `XINFO GROUPS`: `lastDeliveredId` -> `last-delivered-id` [^map-keys]
|
||||||
- `XINFO STREAM`: `radixTreeKeys` -> `radix-tree-keys`, `radixTreeNodes` -> `radix-tree-nodes`, `lastGeneratedId` -> `last-generated-id`, `maxDeletedEntryId` -> `max-deleted-entry-id`, `entriesAdded` -> `entries-added`, `recordedFirstEntryId` -> `recorded-first-entry-id`, `firstEntry` -> `first-entry`, `lastEntry` -> `last-entry`
|
- `XINFO STREAM`: `radixTreeKeys` -> `radix-tree-keys`, `radixTreeNodes` -> `radix-tree-nodes`, `lastGeneratedId` -> `last-generated-id`, `maxDeletedEntryId` -> `max-deleted-entry-id`, `entriesAdded` -> `entries-added`, `recordedFirstEntryId` -> `recorded-first-entry-id`, `firstEntry` -> `first-entry`, `lastEntry` -> `last-entry`
|
||||||
- `XAUTOCLAIM`, `XCLAIM`, `XRANGE`, `XREVRANGE`: `Array<{ name: string; messages: Array<{ id: string; message: Record<string, string> }>; }>` -> `Record<string, Array<{ id: string; message: Record<string, string> }>>`
|
- `XAUTOCLAIM`, `XCLAIM`, `XRANGE`, `XREVRANGE`: `Array<{ name: string; messages: Array<{ id: string; message: Record<string, string> }>; }>` -> `Record<string, Array<{ id: string; message: Record<string, string> }>>`
|
||||||
|
`TOPK.QUERY`: `Array<number>` -> `Array<boolean>`
|
||||||
|
|
||||||
[^enum-to-constants]: TODO
|
[^enum-to-constants]: TODO
|
||||||
|
|
||||||
|
@@ -1,19 +1,19 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './ADD';
|
import ADD from './ADD';
|
||||||
|
|
||||||
describe('BF ADD', () => {
|
describe('BF.ADD', () => {
|
||||||
it('transformArguments', () => {
|
it('transformArguments', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key', 'item'),
|
ADD.transformArguments('key', 'item'),
|
||||||
['BF.ADD', 'key', 'item']
|
['BF.ADD', 'key', 'item']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.bf.add', async client => {
|
testUtils.testWithClient('client.bf.add', async client => {
|
||||||
assert.equal(
|
assert.equal(
|
||||||
await client.bf.add('key', 'item'),
|
await client.bf.add('key', 'item'),
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -1,7 +1,11 @@
|
|||||||
export const FIRST_KEY_INDEX = 1;
|
import { RedisArgument, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
|
import { transformBooleanReply } from '@redis/client/dist/lib/commands/generic-transformers';
|
||||||
|
|
||||||
export function transformArguments(key: string, item: string): Array<string> {
|
export default {
|
||||||
|
FIRST_KEY_INDEX: 1,
|
||||||
|
IS_READ_ONLY: false,
|
||||||
|
transformArguments(key: RedisArgument, item: RedisArgument) {
|
||||||
return ['BF.ADD', key, item];
|
return ['BF.ADD', key, item];
|
||||||
}
|
},
|
||||||
|
transformReply: transformBooleanReply
|
||||||
export { transformBooleanReply as transformReply } from '@redis/client/dist/lib/commands/generic-transformers';
|
} as const satisfies Command;
|
||||||
|
@@ -1,19 +1,19 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './CARD';
|
import CARD from './CARD';
|
||||||
|
|
||||||
describe('BF CARD', () => {
|
describe('BF.CARD', () => {
|
||||||
it('transformArguments', () => {
|
it('transformArguments', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('bloom'),
|
CARD.transformArguments('bloom'),
|
||||||
['BF.CARD', 'bloom']
|
['BF.CARD', 'bloom']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.bf.card', async client => {
|
testUtils.testWithClient('client.bf.card', async client => {
|
||||||
assert.equal(
|
assert.equal(
|
||||||
await client.bf.card('key'),
|
await client.bf.card('key'),
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -1,9 +1,10 @@
|
|||||||
export const FIRST_KEY_INDEX = 1;
|
import { RedisArgument, NumberReply, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
|
|
||||||
export const IS_READ_ONLY = true;
|
export default {
|
||||||
|
FIRST_KEY_INDEX: 1,
|
||||||
export function transformArguments(key: string): Array<string> {
|
IS_READ_ONLY: true,
|
||||||
|
transformArguments(key: RedisArgument) {
|
||||||
return ['BF.CARD', key];
|
return ['BF.CARD', key];
|
||||||
}
|
},
|
||||||
|
transformReply: undefined as unknown as () => NumberReply
|
||||||
export declare function transformReply(): number;
|
} as const satisfies Command;
|
||||||
|
@@ -1,19 +1,19 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './EXISTS';
|
import EXISTS from './EXISTS';
|
||||||
|
|
||||||
describe('BF EXISTS', () => {
|
describe('BF.EXISTS', () => {
|
||||||
it('transformArguments', () => {
|
it('transformArguments', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key', 'item'),
|
EXISTS.transformArguments('key', 'item'),
|
||||||
['BF.EXISTS', 'key', 'item']
|
['BF.EXISTS', 'key', 'item']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.bf.exists', async client => {
|
testUtils.testWithClient('client.bf.exists', async client => {
|
||||||
assert.equal(
|
assert.equal(
|
||||||
await client.bf.exists('key', 'item'),
|
await client.bf.exists('key', 'item'),
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -1,9 +1,11 @@
|
|||||||
export const FIRST_KEY_INDEX = 1;
|
import { RedisArgument, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
|
import { transformBooleanReply } from '@redis/client/dist/lib/commands/generic-transformers';
|
||||||
|
|
||||||
export const IS_READ_ONLY = true;
|
export default {
|
||||||
|
FIRST_KEY_INDEX: 1,
|
||||||
export function transformArguments(key: string, item: string): Array<string> {
|
IS_READ_ONLY: true,
|
||||||
|
transformArguments(key: RedisArgument, item: RedisArgument) {
|
||||||
return ['BF.EXISTS', key, item];
|
return ['BF.EXISTS', key, item];
|
||||||
}
|
},
|
||||||
|
transformReply: transformBooleanReply
|
||||||
export { transformBooleanReply as transformReply } from '@redis/client/dist/lib/commands/generic-transformers';
|
} as const satisfies Command;
|
||||||
|
@@ -1,24 +1,24 @@
|
|||||||
import { strict as assert } from 'assert';
|
// import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
// import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './INFO';
|
// import { transformArguments } from './INFO';
|
||||||
|
|
||||||
describe('BF INFO', () => {
|
// describe('BF INFO', () => {
|
||||||
it('transformArguments', () => {
|
// it('transformArguments', () => {
|
||||||
assert.deepEqual(
|
// assert.deepEqual(
|
||||||
transformArguments('bloom'),
|
// transformArguments('bloom'),
|
||||||
['BF.INFO', 'bloom']
|
// ['BF.INFO', 'bloom']
|
||||||
);
|
// );
|
||||||
});
|
// });
|
||||||
|
|
||||||
testUtils.testWithClient('client.bf.info', async client => {
|
// testUtils.testWithClient('client.bf.info', async client => {
|
||||||
await client.bf.reserve('key', 0.01, 100);
|
// await client.bf.reserve('key', 0.01, 100);
|
||||||
|
|
||||||
const info = await client.bf.info('key');
|
// const info = await client.bf.info('key');
|
||||||
assert.equal(typeof info, 'object');
|
// assert.equal(typeof info, 'object');
|
||||||
assert.equal(info.capacity, 100);
|
// assert.equal(info.capacity, 100);
|
||||||
assert.equal(typeof info.size, 'number');
|
// assert.equal(typeof info.size, 'number');
|
||||||
assert.equal(typeof info.numberOfFilters, 'number');
|
// assert.equal(typeof info.numberOfFilters, 'number');
|
||||||
assert.equal(typeof info.numberOfInsertedItems, 'number');
|
// assert.equal(typeof info.numberOfInsertedItems, 'number');
|
||||||
assert.equal(typeof info.expansionRate, 'number');
|
// assert.equal(typeof info.expansionRate, 'number');
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
// }, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
// });
|
||||||
|
@@ -1,38 +1,57 @@
|
|||||||
export const FIRST_KEY_INDEX = 1;
|
// // export type InfoRawReply = [
|
||||||
|
// // _: string,
|
||||||
|
// // capacity: number,
|
||||||
|
// // _: string,
|
||||||
|
// // size: number,
|
||||||
|
// // _: string,
|
||||||
|
// // numberOfFilters: number,
|
||||||
|
// // _: string,
|
||||||
|
// // numberOfInsertedItems: number,
|
||||||
|
// // _: string,
|
||||||
|
// // expansionRate: number,
|
||||||
|
// // ];
|
||||||
|
|
||||||
export const IS_READ_ONLY = true;
|
// // export interface InfoReply {
|
||||||
|
// // capacity: number;
|
||||||
|
// // size: number;
|
||||||
|
// // numberOfFilters: number;
|
||||||
|
// // numberOfInsertedItems: number;
|
||||||
|
// // expansionRate: number;
|
||||||
|
// // }
|
||||||
|
|
||||||
export function transformArguments(key: string): Array<string> {
|
// // export function transformReply(reply: InfoRawReply): InfoReply {
|
||||||
return ['BF.INFO', key];
|
// // return {
|
||||||
}
|
// // capacity: reply[1],
|
||||||
|
// // size: reply[3],
|
||||||
|
// // numberOfFilters: reply[5],
|
||||||
|
// // numberOfInsertedItems: reply[7],
|
||||||
|
// // expansionRate: reply[9]
|
||||||
|
// // };
|
||||||
|
// // }
|
||||||
|
|
||||||
export type InfoRawReply = [
|
// import { RedisArgument, Command, TuplesToMapReply, BlobStringReply, NumberReply } from '@redis/client/dist/lib/RESP/types';
|
||||||
_: string,
|
// import { transformBooleanArrayReply } from '@redis/client/dist/lib/commands/generic-transformers';
|
||||||
capacity: number,
|
|
||||||
_: string,
|
|
||||||
size: number,
|
|
||||||
_: string,
|
|
||||||
numberOfFilters: number,
|
|
||||||
_: string,
|
|
||||||
numberOfInsertedItems: number,
|
|
||||||
_: string,
|
|
||||||
expansionRate: number,
|
|
||||||
];
|
|
||||||
|
|
||||||
export interface InfoReply {
|
// export type BfInfoReply = TuplesToMapReply<[
|
||||||
capacity: number;
|
// [BlobStringReply<'Capacity'>, NumberReply],
|
||||||
size: number;
|
// [BlobStringReply<'Size'>, NumberReply],
|
||||||
numberOfFilters: number;
|
// [BlobStringReply<'Number of filters'>, NumberReply],
|
||||||
numberOfInsertedItems: number;
|
|
||||||
expansionRate: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function transformReply(reply: InfoRawReply): InfoReply {
|
|
||||||
return {
|
// ]>;
|
||||||
capacity: reply[1],
|
|
||||||
size: reply[3],
|
// export default {
|
||||||
numberOfFilters: reply[5],
|
// FIRST_KEY_INDEX: 1,
|
||||||
numberOfInsertedItems: reply[7],
|
// IS_READ_ONLY: true,
|
||||||
expansionRate: reply[9]
|
// transformArguments(key: RedisArgument) {
|
||||||
};
|
// return ['BF.INFO', key];
|
||||||
}
|
// },
|
||||||
|
// transformReply: {
|
||||||
|
// 2: () => {
|
||||||
|
|
||||||
|
// },
|
||||||
|
// 3: () => {
|
||||||
|
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// } as const satisfies Command;
|
||||||
|
@@ -1,69 +1,69 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './INSERT';
|
import INSERT from './INSERT';
|
||||||
|
|
||||||
describe('BF INSERT', () => {
|
describe('BF.INSERT', () => {
|
||||||
describe('transformArguments', () => {
|
describe('transformArguments', () => {
|
||||||
it('simple', () => {
|
it('simple', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key', 'item'),
|
INSERT.transformArguments('key', 'item'),
|
||||||
['BF.INSERT', 'key', 'ITEMS', 'item']
|
['BF.INSERT', 'key', 'ITEMS', 'item']
|
||||||
);
|
);
|
||||||
});
|
|
||||||
|
|
||||||
it('with CAPACITY', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('key', 'item', { CAPACITY: 100 }),
|
|
||||||
['BF.INSERT', 'key', 'CAPACITY', '100', 'ITEMS', 'item']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('with ERROR', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('key', 'item', { ERROR: 0.01 }),
|
|
||||||
['BF.INSERT', 'key', 'ERROR', '0.01', 'ITEMS', 'item']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('with EXPANSION', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('key', 'item', { EXPANSION: 1 }),
|
|
||||||
['BF.INSERT', 'key', 'EXPANSION', '1', 'ITEMS', 'item']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('with NOCREATE', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('key', 'item', { NOCREATE: true }),
|
|
||||||
['BF.INSERT', 'key', 'NOCREATE', 'ITEMS', 'item']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('with NONSCALING', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('key', 'item', { NONSCALING: true }),
|
|
||||||
['BF.INSERT', 'key', 'NONSCALING', 'ITEMS', 'item']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('with CAPACITY, ERROR, EXPANSION, NOCREATE and NONSCALING', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('key', 'item', {
|
|
||||||
CAPACITY: 100,
|
|
||||||
ERROR: 0.01,
|
|
||||||
EXPANSION: 1,
|
|
||||||
NOCREATE: true,
|
|
||||||
NONSCALING: true
|
|
||||||
}),
|
|
||||||
['BF.INSERT', 'key', 'CAPACITY', '100', 'ERROR', '0.01', 'EXPANSION', '1', 'NOCREATE', 'NONSCALING', 'ITEMS', 'item']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.bf.insert', async client => {
|
it('with CAPACITY', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
await client.bf.insert('key', 'item'),
|
INSERT.transformArguments('key', 'item', { CAPACITY: 100 }),
|
||||||
[true]
|
['BF.INSERT', 'key', 'CAPACITY', '100', 'ITEMS', 'item']
|
||||||
);
|
);
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
});
|
||||||
|
|
||||||
|
it('with ERROR', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
INSERT.transformArguments('key', 'item', { ERROR: 0.01 }),
|
||||||
|
['BF.INSERT', 'key', 'ERROR', '0.01', 'ITEMS', 'item']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with EXPANSION', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
INSERT.transformArguments('key', 'item', { EXPANSION: 1 }),
|
||||||
|
['BF.INSERT', 'key', 'EXPANSION', '1', 'ITEMS', 'item']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with NOCREATE', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
INSERT.transformArguments('key', 'item', { NOCREATE: true }),
|
||||||
|
['BF.INSERT', 'key', 'NOCREATE', 'ITEMS', 'item']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with NONSCALING', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
INSERT.transformArguments('key', 'item', { NONSCALING: true }),
|
||||||
|
['BF.INSERT', 'key', 'NONSCALING', 'ITEMS', 'item']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with CAPACITY, ERROR, EXPANSION, NOCREATE and NONSCALING', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
INSERT.transformArguments('key', 'item', {
|
||||||
|
CAPACITY: 100,
|
||||||
|
ERROR: 0.01,
|
||||||
|
EXPANSION: 1,
|
||||||
|
NOCREATE: true,
|
||||||
|
NONSCALING: true
|
||||||
|
}),
|
||||||
|
['BF.INSERT', 'key', 'CAPACITY', '100', 'ERROR', '0.01', 'EXPANSION', '1', 'NOCREATE', 'NONSCALING', 'ITEMS', 'item']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
testUtils.testWithClient('client.bf.insert', async client => {
|
||||||
|
assert.deepEqual(
|
||||||
|
await client.bf.insert('key', 'item'),
|
||||||
|
[true]
|
||||||
|
);
|
||||||
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -1,45 +1,47 @@
|
|||||||
import { pushVariadicArguments } from '@redis/client/dist/lib/commands/generic-transformers';
|
import { RedisArgument, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
import { RedisCommandArgument, RedisCommandArguments } from '@redis/client/dist/lib/commands';
|
import { RedisVariadicArgument, pushVariadicArguments } from '@redis/client/dist/lib/commands/generic-transformers';
|
||||||
|
import { transformBooleanArrayReply } from '@redis/client/dist/lib/commands/generic-transformers';
|
||||||
|
|
||||||
export const FIRST_KEY_INDEX = 1;
|
export interface BfInsertOptions {
|
||||||
|
CAPACITY?: number;
|
||||||
interface InsertOptions {
|
ERROR?: number;
|
||||||
CAPACITY?: number;
|
EXPANSION?: number;
|
||||||
ERROR?: number;
|
NOCREATE?: boolean;
|
||||||
EXPANSION?: number;
|
NONSCALING?: boolean;
|
||||||
NOCREATE?: true;
|
|
||||||
NONSCALING?: true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function transformArguments(
|
export default {
|
||||||
key: string,
|
FIRST_KEY_INDEX: 1,
|
||||||
items: RedisCommandArgument | Array<RedisCommandArgument>,
|
IS_READ_ONLY: false,
|
||||||
options?: InsertOptions
|
transformArguments(
|
||||||
): RedisCommandArguments {
|
key: RedisArgument,
|
||||||
|
items: RedisVariadicArgument,
|
||||||
|
options?: BfInsertOptions
|
||||||
|
) {
|
||||||
const args = ['BF.INSERT', key];
|
const args = ['BF.INSERT', key];
|
||||||
|
|
||||||
if (options?.CAPACITY) {
|
if (options?.CAPACITY !== undefined) {
|
||||||
args.push('CAPACITY', options.CAPACITY.toString());
|
args.push('CAPACITY', options.CAPACITY.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options?.ERROR) {
|
if (options?.ERROR !== undefined) {
|
||||||
args.push('ERROR', options.ERROR.toString());
|
args.push('ERROR', options.ERROR.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options?.EXPANSION) {
|
if (options?.EXPANSION !== undefined) {
|
||||||
args.push('EXPANSION', options.EXPANSION.toString());
|
args.push('EXPANSION', options.EXPANSION.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options?.NOCREATE) {
|
if (options?.NOCREATE) {
|
||||||
args.push('NOCREATE');
|
args.push('NOCREATE');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options?.NONSCALING) {
|
if (options?.NONSCALING) {
|
||||||
args.push('NONSCALING');
|
args.push('NONSCALING');
|
||||||
}
|
}
|
||||||
|
|
||||||
args.push('ITEMS');
|
args.push('ITEMS');
|
||||||
return pushVariadicArguments(args, items);
|
return pushVariadicArguments(args, items);
|
||||||
}
|
},
|
||||||
|
transformReply: transformBooleanArrayReply
|
||||||
export { transformBooleanArrayReply as transformReply } from '@redis/client/dist/lib/commands/generic-transformers';
|
} as const satisfies Command;
|
||||||
|
@@ -1,28 +1,35 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './LOADCHUNK';
|
import LOADCHUNK from './LOADCHUNK';
|
||||||
|
import { RESP_TYPES } from '@redis/client';
|
||||||
|
|
||||||
describe('BF LOADCHUNK', () => {
|
describe('BF.LOADCHUNK', () => {
|
||||||
it('transformArguments', () => {
|
it('transformArguments', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key', 0, ''),
|
LOADCHUNK.transformArguments('key', 0, ''),
|
||||||
['BF.LOADCHUNK', 'key', '0', '']
|
['BF.LOADCHUNK', 'key', '0', '']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.bf.loadChunk', async client => {
|
testUtils.testWithClient('client.bf.loadChunk', async client => {
|
||||||
const [, { iterator, chunk }] = await Promise.all([
|
const [, { iterator, chunk }] = await Promise.all([
|
||||||
client.bf.reserve('source', 0.01, 100),
|
client.bf.reserve('source', 0.01, 100),
|
||||||
client.bf.scanDump(
|
client.bf.scanDump('source', 0)
|
||||||
client.commandOptions({ returnBuffers: true }),
|
]);
|
||||||
'source',
|
|
||||||
0
|
|
||||||
)
|
|
||||||
]);
|
|
||||||
|
|
||||||
assert.equal(
|
assert.equal(
|
||||||
await client.bf.loadChunk('destination', iterator, chunk),
|
await client.bf.loadChunk('destination', iterator, chunk),
|
||||||
'OK'
|
'OK'
|
||||||
);
|
);
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
}, {
|
||||||
|
...GLOBAL.SERVERS.OPEN,
|
||||||
|
clientOptions: {
|
||||||
|
...GLOBAL.SERVERS.OPEN.clientOptions,
|
||||||
|
commandOptions: {
|
||||||
|
typeMapping: {
|
||||||
|
[RESP_TYPES.BLOB_STRING]: Buffer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@@ -1,13 +1,10 @@
|
|||||||
import { RedisCommandArgument, RedisCommandArguments } from '@redis/client/dist/lib/commands';
|
import { RedisArgument, SimpleStringReply, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
|
|
||||||
export const FIRST_KEY_INDEX = 1;
|
export default {
|
||||||
|
FIRST_KEY_INDEX: 1,
|
||||||
export function transformArguments(
|
IS_READ_ONLY: false,
|
||||||
key: string,
|
transformArguments(key: RedisArgument, iterator: number, chunk: RedisArgument) {
|
||||||
iteretor: number,
|
return ['BF.LOADCHUNK', key, iterator.toString(), chunk];
|
||||||
chunk: RedisCommandArgument
|
},
|
||||||
): RedisCommandArguments {
|
transformReply: undefined as unknown as () => SimpleStringReply<'OK'>
|
||||||
return ['BF.LOADCHUNK', key, iteretor.toString(), chunk];
|
} as const satisfies Command;
|
||||||
}
|
|
||||||
|
|
||||||
export declare function transformReply(): 'OK';
|
|
||||||
|
@@ -1,19 +1,19 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './MADD';
|
import MADD from './MADD';
|
||||||
|
|
||||||
describe('BF MADD', () => {
|
describe('BF.MADD', () => {
|
||||||
it('transformArguments', () => {
|
it('transformArguments', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key', ['1', '2']),
|
MADD.transformArguments('key', ['1', '2']),
|
||||||
['BF.MADD', 'key', '1', '2']
|
['BF.MADD', 'key', '1', '2']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.ts.mAdd', async client => {
|
testUtils.testWithClient('client.ts.mAdd', async client => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
await client.bf.mAdd('key', ['1', '2']),
|
await client.bf.mAdd('key', ['1', '2']),
|
||||||
[true, true]
|
[true, true]
|
||||||
);
|
);
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -1,7 +1,12 @@
|
|||||||
export const FIRST_KEY_INDEX = 1;
|
import { RedisArgument, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
|
import { RedisVariadicArgument, pushVariadicArguments } from '@redis/client/dist/lib/commands/generic-transformers';
|
||||||
|
import { transformBooleanArrayReply } from '@redis/client/dist/lib/commands/generic-transformers';
|
||||||
|
|
||||||
export function transformArguments(key: string, items: Array<string>): Array<string> {
|
export default {
|
||||||
return ['BF.MADD', key, ...items];
|
FIRST_KEY_INDEX: 1,
|
||||||
}
|
IS_READ_ONLY: false,
|
||||||
|
transformArguments(key: RedisArgument, items: RedisVariadicArgument) {
|
||||||
export { transformBooleanArrayReply as transformReply } from '@redis/client/dist/lib/commands/generic-transformers';
|
return pushVariadicArguments(['BF.MADD', key], items);
|
||||||
|
},
|
||||||
|
transformReply: transformBooleanArrayReply
|
||||||
|
} as const satisfies Command;
|
||||||
|
@@ -1,19 +1,19 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './MEXISTS';
|
import MEXISTS from './MEXISTS';
|
||||||
|
|
||||||
describe('BF MEXISTS', () => {
|
describe('BF.MEXISTS', () => {
|
||||||
it('transformArguments', () => {
|
it('transformArguments', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key', ['1', '2']),
|
MEXISTS.transformArguments('key', ['1', '2']),
|
||||||
['BF.MEXISTS', 'key', '1', '2']
|
['BF.MEXISTS', 'key', '1', '2']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.bf.mExists', async client => {
|
testUtils.testWithClient('client.bf.mExists', async client => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
await client.bf.mExists('key', ['1', '2']),
|
await client.bf.mExists('key', ['1', '2']),
|
||||||
[false, false]
|
[false, false]
|
||||||
);
|
);
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -1,9 +1,12 @@
|
|||||||
export const FIRST_KEY_INDEX = 1;
|
import { RedisArgument, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
|
import { RedisVariadicArgument, pushVariadicArguments } from '@redis/client/dist/lib/commands/generic-transformers';
|
||||||
|
import { transformBooleanArrayReply } from '@redis/client/dist/lib/commands/generic-transformers';
|
||||||
|
|
||||||
export const IS_READ_ONLY = true;
|
export default {
|
||||||
|
FIRST_KEY_INDEX: 1,
|
||||||
export function transformArguments(key: string, items: Array<string>): Array<string> {
|
IS_READ_ONLY: true,
|
||||||
return ['BF.MEXISTS', key, ...items];
|
transformArguments(key: RedisArgument, items: RedisVariadicArgument) {
|
||||||
}
|
return pushVariadicArguments(['BF.MEXISTS', key], items);
|
||||||
|
},
|
||||||
export { transformBooleanArrayReply as transformReply } from '@redis/client/dist/lib/commands/generic-transformers';
|
transformReply: transformBooleanArrayReply
|
||||||
|
} as const satisfies Command;
|
||||||
|
@@ -1,49 +1,49 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './RESERVE';
|
import RESERVE from './RESERVE';
|
||||||
|
|
||||||
describe('BF RESERVE', () => {
|
describe('BF.RESERVE', () => {
|
||||||
describe('transformArguments', () => {
|
describe('transformArguments', () => {
|
||||||
it('simple', () => {
|
it('simple', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key', 0.01, 100),
|
RESERVE.transformArguments('key', 0.01, 100),
|
||||||
['BF.RESERVE', 'key', '0.01', '100']
|
['BF.RESERVE', 'key', '0.01', '100']
|
||||||
);
|
);
|
||||||
});
|
|
||||||
|
|
||||||
it('with EXPANSION', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('key', 0.01, 100, {
|
|
||||||
EXPANSION: 1
|
|
||||||
}),
|
|
||||||
['BF.RESERVE', 'key', '0.01', '100', 'EXPANSION', '1']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('with NONSCALING', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('key', 0.01, 100, {
|
|
||||||
NONSCALING: true
|
|
||||||
}),
|
|
||||||
['BF.RESERVE', 'key', '0.01', '100', 'NONSCALING']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('with EXPANSION and NONSCALING', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('key', 0.01, 100, {
|
|
||||||
EXPANSION: 1,
|
|
||||||
NONSCALING: true
|
|
||||||
}),
|
|
||||||
['BF.RESERVE', 'key', '0.01', '100', 'EXPANSION', '1', 'NONSCALING']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.bf.reserve', async client => {
|
it('with EXPANSION', () => {
|
||||||
assert.equal(
|
assert.deepEqual(
|
||||||
await client.bf.reserve('bloom', 0.01, 100),
|
RESERVE.transformArguments('key', 0.01, 100, {
|
||||||
'OK'
|
EXPANSION: 1
|
||||||
);
|
}),
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
['BF.RESERVE', 'key', '0.01', '100', 'EXPANSION', '1']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with NONSCALING', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
RESERVE.transformArguments('key', 0.01, 100, {
|
||||||
|
NONSCALING: true
|
||||||
|
}),
|
||||||
|
['BF.RESERVE', 'key', '0.01', '100', 'NONSCALING']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with EXPANSION and NONSCALING', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
RESERVE.transformArguments('key', 0.01, 100, {
|
||||||
|
EXPANSION: 1,
|
||||||
|
NONSCALING: true
|
||||||
|
}),
|
||||||
|
['BF.RESERVE', 'key', '0.01', '100', 'EXPANSION', '1', 'NONSCALING']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
testUtils.testWithClient('client.bf.reserve', async client => {
|
||||||
|
assert.equal(
|
||||||
|
await client.bf.reserve('bloom', 0.01, 100),
|
||||||
|
'OK'
|
||||||
|
);
|
||||||
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -1,16 +1,20 @@
|
|||||||
export const FIRST_KEY_INDEX = 1;
|
import { RedisArgument, SimpleStringReply, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
|
import { RedisVariadicArgument, pushVariadicArguments } from '@redis/client/dist/lib/commands/generic-transformers';
|
||||||
|
|
||||||
interface ReserveOptions {
|
export interface BfReserveOptions {
|
||||||
EXPANSION?: number;
|
EXPANSION?: number;
|
||||||
NONSCALING?: true;
|
NONSCALING?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function transformArguments(
|
export default {
|
||||||
key: string,
|
FIRST_KEY_INDEX: 1,
|
||||||
|
IS_READ_ONLY: true,
|
||||||
|
transformArguments(
|
||||||
|
key: RedisArgument,
|
||||||
errorRate: number,
|
errorRate: number,
|
||||||
capacity: number,
|
capacity: number,
|
||||||
options?: ReserveOptions
|
options?: BfReserveOptions
|
||||||
): Array<string> {
|
) {
|
||||||
const args = ['BF.RESERVE', key, errorRate.toString(), capacity.toString()];
|
const args = ['BF.RESERVE', key, errorRate.toString(), capacity.toString()];
|
||||||
|
|
||||||
if (options?.EXPANSION) {
|
if (options?.EXPANSION) {
|
||||||
@@ -22,6 +26,6 @@ export function transformArguments(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return args;
|
return args;
|
||||||
}
|
},
|
||||||
|
transformReply: undefined as unknown as () => SimpleStringReply<'OK'>
|
||||||
export declare function transformReply(): 'OK';
|
} as const satisfies Command;
|
||||||
|
@@ -1,22 +1,22 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './SCANDUMP';
|
import SCANDUMP from './SCANDUMP';
|
||||||
|
|
||||||
describe('BF SCANDUMP', () => {
|
describe('BF.SCANDUMP', () => {
|
||||||
it('transformArguments', () => {
|
it('transformArguments', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key', 0),
|
SCANDUMP.transformArguments('key', 0),
|
||||||
['BF.SCANDUMP', 'key', '0']
|
['BF.SCANDUMP', 'key', '0']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.bf.scanDump', async client => {
|
testUtils.testWithClient('client.bf.scanDump', async client => {
|
||||||
const [, dump] = await Promise.all([
|
const [, dump] = await Promise.all([
|
||||||
client.bf.reserve('key', 0.01, 100),
|
client.bf.reserve('key', 0.01, 100),
|
||||||
client.bf.scanDump('key', 0)
|
client.bf.scanDump('key', 0)
|
||||||
]);
|
]);
|
||||||
assert.equal(typeof dump, 'object');
|
assert.equal(typeof dump, 'object');
|
||||||
assert.equal(typeof dump.iterator, 'number');
|
assert.equal(typeof dump.iterator, 'number');
|
||||||
assert.equal(typeof dump.chunk, 'string');
|
assert.equal(typeof dump.chunk, 'string');
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -1,24 +1,15 @@
|
|||||||
export const FIRST_KEY_INDEX = 1;
|
import { RedisArgument, TuplesReply, NumberReply, BlobStringReply, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
|
|
||||||
export const IS_READ_ONLY = true;
|
export default {
|
||||||
|
FIRST_KEY_INDEX: 1,
|
||||||
export function transformArguments(key: string, iterator: number): Array<string> {
|
IS_READ_ONLY: true,
|
||||||
|
transformArguments(key: RedisArgument, iterator: number) {
|
||||||
return ['BF.SCANDUMP', key, iterator.toString()];
|
return ['BF.SCANDUMP', key, iterator.toString()];
|
||||||
}
|
},
|
||||||
|
transformReply(reply: TuplesReply<[NumberReply, BlobStringReply]>) {
|
||||||
type ScanDumpRawReply = [
|
|
||||||
iterator: number,
|
|
||||||
chunk: string
|
|
||||||
];
|
|
||||||
|
|
||||||
interface ScanDumpReply {
|
|
||||||
iterator: number;
|
|
||||||
chunk: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function transformReply([iterator, chunk]: ScanDumpRawReply): ScanDumpReply {
|
|
||||||
return {
|
return {
|
||||||
iterator,
|
iterator: reply[0],
|
||||||
chunk
|
chunk: reply[1]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
} as const satisfies Command;
|
||||||
|
@@ -1,33 +1,45 @@
|
|||||||
import * as ADD from './ADD';
|
import type { RedisCommands } from '@redis/client/dist/lib/RESP/types';
|
||||||
import * as CARD from './CARD';
|
import ADD from './ADD';
|
||||||
import * as EXISTS from './EXISTS';
|
import CARD from './CARD';
|
||||||
import * as INFO from './INFO';
|
import EXISTS from './EXISTS';
|
||||||
import * as INSERT from './INSERT';
|
// import INFO from './INFO';
|
||||||
import * as LOADCHUNK from './LOADCHUNK';
|
import INSERT from './INSERT';
|
||||||
import * as MADD from './MADD';
|
import LOADCHUNK from './LOADCHUNK';
|
||||||
import * as MEXISTS from './MEXISTS';
|
import MADD from './MADD';
|
||||||
import * as RESERVE from './RESERVE';
|
import MEXISTS from './MEXISTS';
|
||||||
import * as SCANDUMP from './SCANDUMP';
|
import RESERVE from './RESERVE';
|
||||||
|
import SCANDUMP from './SCANDUMP';
|
||||||
|
|
||||||
|
type ADD = typeof import('./ADD').default;
|
||||||
|
type CARD = typeof import('./CARD').default;
|
||||||
|
type EXISTS = typeof import('./EXISTS').default;
|
||||||
|
// type INFO = typeof import('./INFO').default;
|
||||||
|
type INSERT = typeof import('./INSERT').default;
|
||||||
|
type LOADCHUNK = typeof import('./LOADCHUNK').default;
|
||||||
|
type MADD = typeof import('./MADD').default;
|
||||||
|
type MEXISTS = typeof import('./MEXISTS').default;
|
||||||
|
type RESERVE = typeof import('./RESERVE').default;
|
||||||
|
type SCANDUMP = typeof import('./SCANDUMP').default;
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
ADD,
|
ADD: ADD as ADD,
|
||||||
add: ADD,
|
add: ADD as ADD,
|
||||||
CARD,
|
CARD: CARD as CARD,
|
||||||
card: CARD,
|
card: CARD as CARD,
|
||||||
EXISTS,
|
EXISTS: EXISTS as EXISTS,
|
||||||
exists: EXISTS,
|
exists: EXISTS as EXISTS,
|
||||||
INFO,
|
// INFO: INFO as INFO,
|
||||||
info: INFO,
|
// info: INFO as INFO,
|
||||||
INSERT,
|
INSERT: INSERT as INSERT,
|
||||||
insert: INSERT,
|
insert: INSERT as INSERT,
|
||||||
LOADCHUNK,
|
LOADCHUNK: LOADCHUNK as LOADCHUNK,
|
||||||
loadChunk: LOADCHUNK,
|
loadChunk: LOADCHUNK as LOADCHUNK,
|
||||||
MADD,
|
MADD: MADD as MADD,
|
||||||
mAdd: MADD,
|
mAdd: MADD as MADD,
|
||||||
MEXISTS,
|
MEXISTS: MEXISTS as MEXISTS,
|
||||||
mExists: MEXISTS,
|
mExists: MEXISTS as MEXISTS,
|
||||||
RESERVE,
|
RESERVE: RESERVE as RESERVE,
|
||||||
reserve: RESERVE,
|
reserve: RESERVE as RESERVE,
|
||||||
SCANDUMP,
|
SCANDUMP: SCANDUMP as SCANDUMP,
|
||||||
scanDump: SCANDUMP
|
scanDump: SCANDUMP as SCANDUMP
|
||||||
};
|
} satisfies RedisCommands;
|
||||||
|
@@ -1,41 +1,42 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './INCRBY';
|
import INCRBY from './INCRBY';
|
||||||
|
|
||||||
describe('CMS INCRBY', () => {
|
describe('CMS.INCRBY', () => {
|
||||||
describe('transformArguments', () => {
|
describe('transformArguments', () => {
|
||||||
it('single item', () => {
|
it('single item', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key', {
|
INCRBY.transformArguments('key', {
|
||||||
item: 'item',
|
item: 'item',
|
||||||
incrementBy: 1
|
incrementBy: 1
|
||||||
}),
|
}),
|
||||||
['CMS.INCRBY', 'key', 'item', '1']
|
['CMS.INCRBY', 'key', 'item', '1']
|
||||||
);
|
);
|
||||||
});
|
|
||||||
|
|
||||||
it('multiple items', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('key', [{
|
|
||||||
item: 'a',
|
|
||||||
incrementBy: 1
|
|
||||||
}, {
|
|
||||||
item: 'b',
|
|
||||||
incrementBy: 2
|
|
||||||
}]),
|
|
||||||
['CMS.INCRBY', 'key', 'a', '1', 'b', '2']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.cms.incrBy', async client => {
|
it('multiple items', () => {
|
||||||
await client.cms.initByDim('key', 1000, 5);
|
assert.deepEqual(
|
||||||
assert.deepEqual(
|
INCRBY.transformArguments('key', [{
|
||||||
await client.cms.incrBy('key', {
|
item: 'a',
|
||||||
item: 'item',
|
incrementBy: 1
|
||||||
incrementBy: 1
|
}, {
|
||||||
}),
|
item: 'b',
|
||||||
[1]
|
incrementBy: 2
|
||||||
);
|
}]),
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
['CMS.INCRBY', 'key', 'a', '1', 'b', '2']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
testUtils.testWithClient('client.cms.incrBy', async client => {
|
||||||
|
const [, reply] = await Promise.all([
|
||||||
|
client.cms.initByDim('key', 1000, 5),
|
||||||
|
client.cms.incrBy('key', {
|
||||||
|
item: 'item',
|
||||||
|
incrementBy: 1
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
|
||||||
|
assert.deepEqual(reply, [1]);
|
||||||
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -1,29 +1,32 @@
|
|||||||
export const FIRST_KEY_INDEX = 1;
|
import { RedisArgument, ArrayReply, NumberReply, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
|
|
||||||
interface IncrByItem {
|
export interface BfIncrByItem {
|
||||||
item: string;
|
item: RedisArgument;
|
||||||
incrementBy: number;
|
incrementBy: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function transformArguments(
|
export default {
|
||||||
key: string,
|
FIRST_KEY_INDEX: 1,
|
||||||
items: IncrByItem | Array<IncrByItem>
|
IS_READ_ONLY: false,
|
||||||
): Array<string> {
|
transformArguments(
|
||||||
|
key: RedisArgument,
|
||||||
|
items: BfIncrByItem | Array<BfIncrByItem>
|
||||||
|
) {
|
||||||
const args = ['CMS.INCRBY', key];
|
const args = ['CMS.INCRBY', key];
|
||||||
|
|
||||||
if (Array.isArray(items)) {
|
if (Array.isArray(items)) {
|
||||||
for (const item of items) {
|
for (const item of items) {
|
||||||
pushIncrByItem(args, item);
|
pushIncrByItem(args, item);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pushIncrByItem(args, items);
|
pushIncrByItem(args, items);
|
||||||
}
|
}
|
||||||
|
|
||||||
return args;
|
return args;
|
||||||
}
|
},
|
||||||
|
transformReply: undefined as unknown as () => ArrayReply<NumberReply>
|
||||||
|
} as const satisfies Command;
|
||||||
|
|
||||||
function pushIncrByItem(args: Array<string>, { item, incrementBy }: IncrByItem): void {
|
function pushIncrByItem(args: Array<RedisArgument>, { item, incrementBy }: BfIncrByItem): void {
|
||||||
args.push(item, incrementBy.toString());
|
args.push(item, incrementBy.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
export declare function transformReply(): Array<number>;
|
|
||||||
|
@@ -1,25 +1,27 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './INFO';
|
import INFO from './INFO';
|
||||||
|
|
||||||
describe('CMS INFO', () => {
|
describe('CMS.INFO', () => {
|
||||||
it('transformArguments', () => {
|
it('transformArguments', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key'),
|
INFO.transformArguments('key'),
|
||||||
['CMS.INFO', 'key']
|
['CMS.INFO', 'key']
|
||||||
);
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
testUtils.testWithClient('client.cms.info', async client => {
|
||||||
|
const width = 1000,
|
||||||
|
depth = 5,
|
||||||
|
[, reply] = await Promise.all([
|
||||||
|
client.cms.initByDim('key', width, depth),
|
||||||
|
client.cms.info('key')
|
||||||
|
]);
|
||||||
|
|
||||||
|
assert.deepEqual(reply, {
|
||||||
|
width,
|
||||||
|
depth,
|
||||||
|
count: 0
|
||||||
});
|
});
|
||||||
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
testUtils.testWithClient('client.cms.info', async client => {
|
|
||||||
await client.cms.initByDim('key', 1000, 5);
|
|
||||||
|
|
||||||
assert.deepEqual(
|
|
||||||
await client.cms.info('key'),
|
|
||||||
{
|
|
||||||
width: 1000,
|
|
||||||
depth: 5,
|
|
||||||
count: 0
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
|
||||||
});
|
});
|
||||||
|
@@ -1,30 +1,23 @@
|
|||||||
export const FIRST_KEY_INDEX = 1;
|
import { RedisArgument, TuplesToMapReply, BlobStringReply, NumberReply, Resp2Reply, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
|
|
||||||
export const IS_READ_ONLY = true;
|
export type BfInfoReply = TuplesToMapReply<[
|
||||||
|
[BlobStringReply<'width'>, NumberReply],
|
||||||
|
[BlobStringReply<'depth'>, NumberReply],
|
||||||
|
[BlobStringReply<'count'>, NumberReply]
|
||||||
|
]>;
|
||||||
|
|
||||||
export function transformArguments(key: string): Array<string> {
|
export default {
|
||||||
|
FIRST_KEY_INDEX: 1,
|
||||||
|
IS_READ_ONLY: true,
|
||||||
|
transformArguments(key: RedisArgument) {
|
||||||
return ['CMS.INFO', key];
|
return ['CMS.INFO', key];
|
||||||
}
|
},
|
||||||
|
transformReply: {
|
||||||
export type InfoRawReply = [
|
2: (reply: Resp2Reply<BfInfoReply>) => ({
|
||||||
_: string,
|
width: reply[1],
|
||||||
width: number,
|
depth: reply[3],
|
||||||
_: string,
|
count: reply[5]
|
||||||
depth: number,
|
}),
|
||||||
_: string,
|
3: undefined as unknown as () => BfInfoReply
|
||||||
count: number
|
}
|
||||||
];
|
} as const satisfies Command;
|
||||||
|
|
||||||
export interface InfoReply {
|
|
||||||
width: number;
|
|
||||||
depth: number;
|
|
||||||
count: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function transformReply(reply: InfoRawReply): InfoReply {
|
|
||||||
return {
|
|
||||||
width: reply[1],
|
|
||||||
depth: reply[3],
|
|
||||||
count: reply[5]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
@@ -1,19 +1,19 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './INITBYDIM';
|
import INITBYDIM from './INITBYDIM';
|
||||||
|
|
||||||
describe('CMS INITBYDIM', () => {
|
describe('CMS.INITBYDIM', () => {
|
||||||
it('transformArguments', () => {
|
it('transformArguments', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key', 1000, 5),
|
INITBYDIM.transformArguments('key', 1000, 5),
|
||||||
['CMS.INITBYDIM', 'key', '1000', '5']
|
['CMS.INITBYDIM', 'key', '1000', '5']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.cms.initByDim', async client => {
|
testUtils.testWithClient('client.cms.initByDim', async client => {
|
||||||
assert.equal(
|
assert.equal(
|
||||||
await client.cms.initByDim('key', 1000, 5),
|
await client.cms.initByDim('key', 1000, 5),
|
||||||
'OK'
|
'OK'
|
||||||
);
|
);
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -1,7 +1,10 @@
|
|||||||
export const FIRST_KEY_INDEX = 1;
|
import { RedisArgument, SimpleStringReply, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
|
|
||||||
export function transformArguments(key: string, width: number, depth: number): Array<string> {
|
export default {
|
||||||
|
FIRST_KEY_INDEX: 1,
|
||||||
|
IS_READ_ONLY: false,
|
||||||
|
transformArguments(key: RedisArgument, width: number, depth: number) {
|
||||||
return ['CMS.INITBYDIM', key, width.toString(), depth.toString()];
|
return ['CMS.INITBYDIM', key, width.toString(), depth.toString()];
|
||||||
}
|
},
|
||||||
|
transformReply: undefined as unknown as () => SimpleStringReply<'OK'>
|
||||||
export declare function transformReply(): 'OK';
|
} as const satisfies Command;
|
||||||
|
@@ -1,19 +1,19 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './INITBYPROB';
|
import INITBYPROB from './INITBYPROB';
|
||||||
|
|
||||||
describe('CMS INITBYPROB', () => {
|
describe('CMS.INITBYPROB', () => {
|
||||||
it('transformArguments', () => {
|
it('transformArguments', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key', 0.001, 0.01),
|
INITBYPROB.transformArguments('key', 0.001, 0.01),
|
||||||
['CMS.INITBYPROB', 'key', '0.001', '0.01']
|
['CMS.INITBYPROB', 'key', '0.001', '0.01']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.cms.initByProb', async client => {
|
testUtils.testWithClient('client.cms.initByProb', async client => {
|
||||||
assert.equal(
|
assert.equal(
|
||||||
await client.cms.initByProb('key', 0.001, 0.01),
|
await client.cms.initByProb('key', 0.001, 0.01),
|
||||||
'OK'
|
'OK'
|
||||||
);
|
);
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -1,7 +1,10 @@
|
|||||||
export const FIRST_KEY_INDEX = 1;
|
import { RedisArgument, SimpleStringReply, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
|
|
||||||
export function transformArguments(key: string, error: number, probability: number): Array<string> {
|
export default {
|
||||||
|
FIRST_KEY_INDEX: 1,
|
||||||
|
IS_READ_ONLY: false,
|
||||||
|
transformArguments(key: RedisArgument, error: number, probability: number) {
|
||||||
return ['CMS.INITBYPROB', key, error.toString(), probability.toString()];
|
return ['CMS.INITBYPROB', key, error.toString(), probability.toString()];
|
||||||
}
|
},
|
||||||
|
transformReply: undefined as unknown as () => SimpleStringReply<'OK'>
|
||||||
export declare function transformReply(): 'OK';
|
} as const satisfies Command;
|
||||||
|
@@ -1,36 +1,34 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './MERGE';
|
import MERGE from './MERGE';
|
||||||
|
|
||||||
describe('CMS MERGE', () => {
|
describe('CMS.MERGE', () => {
|
||||||
describe('transformArguments', () => {
|
describe('transformArguments', () => {
|
||||||
it('without WEIGHTS', () => {
|
it('without WEIGHTS', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('dest', ['src']),
|
MERGE.transformArguments('destination', ['source']),
|
||||||
['CMS.MERGE', 'dest', '1', 'src']
|
['CMS.MERGE', 'destination', '1', 'source']
|
||||||
);
|
);
|
||||||
});
|
|
||||||
|
|
||||||
it('with WEIGHTS', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('dest', [{
|
|
||||||
name: 'src',
|
|
||||||
weight: 1
|
|
||||||
}]),
|
|
||||||
['CMS.MERGE', 'dest', '1', 'src', 'WEIGHTS', '1']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.cms.merge', async client => {
|
it('with WEIGHTS', () => {
|
||||||
await Promise.all([
|
assert.deepEqual(
|
||||||
client.cms.initByDim('src', 1000, 5),
|
MERGE.transformArguments('destination', [{
|
||||||
client.cms.initByDim('dest', 1000, 5),
|
name: 'source',
|
||||||
]);
|
weight: 1
|
||||||
|
}]),
|
||||||
|
['CMS.MERGE', 'destination', '1', 'source', 'WEIGHTS', '1']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
assert.equal(
|
testUtils.testWithClient('client.cms.merge', async client => {
|
||||||
await client.cms.merge('dest', ['src']),
|
const [, , reply] = await Promise.all([
|
||||||
'OK'
|
client.cms.initByDim('source', 1000, 5),
|
||||||
);
|
client.cms.initByDim('destination', 1000, 5),
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
client.cms.merge('destination', ['source'])
|
||||||
|
]);
|
||||||
|
|
||||||
|
assert.equal(reply, 'OK');
|
||||||
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -1,37 +1,37 @@
|
|||||||
export const FIRST_KEY_INDEX = 1;
|
import { RedisArgument, SimpleStringReply, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
|
|
||||||
interface Sketch {
|
interface BfMergeSketch {
|
||||||
name: string;
|
name: RedisArgument;
|
||||||
weight: number;
|
weight: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
type Sketches = Array<string> | Array<Sketch>;
|
export type BfMergeSketches = Array<RedisArgument> | Array<BfMergeSketch>;
|
||||||
|
|
||||||
export function transformArguments(dest: string, src: Sketches): Array<string> {
|
export default {
|
||||||
const args = [
|
FIRST_KEY_INDEX: 1,
|
||||||
'CMS.MERGE',
|
IS_READ_ONLY: false,
|
||||||
dest,
|
transformArguments(
|
||||||
src.length.toString()
|
destination: RedisArgument,
|
||||||
];
|
source: BfMergeSketches
|
||||||
|
) {
|
||||||
|
let args = ['CMS.MERGE', destination, source.length.toString()];
|
||||||
|
|
||||||
if (isStringSketches(src)) {
|
if (isPlainSketches(source)) {
|
||||||
args.push(...src);
|
args = args.concat(source);
|
||||||
} else {
|
} else {
|
||||||
for (const sketch of src) {
|
const { length } = args;
|
||||||
args.push(sketch.name);
|
args[length + source.length] = 'WEIGHTS';
|
||||||
}
|
for (let i = 0; i < source.length; i++) {
|
||||||
|
args[length + i] = source[i].name;
|
||||||
args.push('WEIGHTS');
|
args[length + source.length + i + 1] = source[i].weight.toString();
|
||||||
for (const sketch of src) {
|
}
|
||||||
args.push(sketch.weight.toString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return args;
|
return args;
|
||||||
}
|
},
|
||||||
|
transformReply: undefined as unknown as () => SimpleStringReply<'OK'>
|
||||||
|
} as const satisfies Command;
|
||||||
|
|
||||||
function isStringSketches(src: Sketches): src is Array<string> {
|
function isPlainSketches(src: BfMergeSketches): src is Array<RedisArgument> {
|
||||||
return typeof src[0] === 'string';
|
return typeof src[0] === 'string' || src[0] instanceof Buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
export declare function transformReply(): 'OK';
|
|
||||||
|
@@ -1,22 +1,21 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './QUERY';
|
import QUERY from './QUERY';
|
||||||
|
|
||||||
describe('CMS QUERY', () => {
|
describe('CMS.QUERY', () => {
|
||||||
it('transformArguments', () => {
|
it('transformArguments', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key', 'item'),
|
QUERY.transformArguments('key', 'item'),
|
||||||
['CMS.QUERY', 'key', 'item']
|
['CMS.QUERY', 'key', 'item']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.cms.query', async client => {
|
testUtils.testWithClient('client.cms.query', async client => {
|
||||||
await client.cms.initByDim('key', 1000, 5);
|
const [, reply] = await Promise.all([
|
||||||
|
client.cms.initByDim('key', 1000, 5),
|
||||||
|
client.cms.query('key', 'item')
|
||||||
|
]);
|
||||||
|
|
||||||
assert.deepEqual(
|
assert.deepEqual(reply, [0]);
|
||||||
await client.cms.query('key', 'item'),
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
[0]
|
|
||||||
);
|
|
||||||
|
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
|
||||||
});
|
});
|
||||||
|
@@ -1,15 +1,11 @@
|
|||||||
import { RedisCommandArguments } from '@redis/client/dist/lib/commands';
|
import { ArrayReply, NumberReply, Command, RedisArgument } from '@redis/client/dist/lib/RESP/types';
|
||||||
import { pushVariadicArguments } from '@redis/client/dist/lib/commands/generic-transformers';
|
import { RedisVariadicArgument, pushVariadicArguments } from '@redis/client/dist/lib/commands/generic-transformers';
|
||||||
|
|
||||||
export const FIRST_KEY_INDEX = 1;
|
export default {
|
||||||
|
FIRST_KEY_INDEX: 1,
|
||||||
export const IS_READ_ONLY = true;
|
IS_READ_ONLY: true,
|
||||||
|
transformArguments(key: RedisArgument, items: RedisVariadicArgument) {
|
||||||
export function transformArguments(
|
|
||||||
key: string,
|
|
||||||
items: string | Array<string>
|
|
||||||
): RedisCommandArguments {
|
|
||||||
return pushVariadicArguments(['CMS.QUERY', key], items);
|
return pushVariadicArguments(['CMS.QUERY', key], items);
|
||||||
}
|
},
|
||||||
|
transformReply: undefined as unknown as () => ArrayReply<NumberReply>
|
||||||
export declare function transformReply(): Array<number>;
|
} as const satisfies Command;
|
||||||
|
@@ -1,21 +1,29 @@
|
|||||||
import * as INCRBY from './INCRBY';
|
import type { RedisCommands } from '@redis/client/dist/lib/RESP/types';
|
||||||
import * as INFO from './INFO';
|
import INCRBY from './INCRBY';
|
||||||
import * as INITBYDIM from './INITBYDIM';
|
import INFO from './INFO';
|
||||||
import * as INITBYPROB from './INITBYPROB';
|
import INITBYDIM from './INITBYDIM';
|
||||||
import * as MERGE from './MERGE';
|
import INITBYPROB from './INITBYPROB';
|
||||||
import * as QUERY from './QUERY';
|
import MERGE from './MERGE';
|
||||||
|
import QUERY from './QUERY';
|
||||||
|
|
||||||
|
type INCRBY = typeof import('./INCRBY').default;
|
||||||
|
type INFO = typeof import('./INFO').default;
|
||||||
|
type INITBYDIM = typeof import('./INITBYDIM').default;
|
||||||
|
type INITBYPROB = typeof import('./INITBYPROB').default;
|
||||||
|
type MERGE = typeof import('./MERGE').default;
|
||||||
|
type QUERY = typeof import('./QUERY').default;
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
INCRBY,
|
INCRBY: INCRBY as INCRBY,
|
||||||
incrBy: INCRBY,
|
incrBy: INCRBY as INCRBY,
|
||||||
INFO,
|
INFO: INFO as INFO,
|
||||||
info: INFO,
|
info: INFO as INFO,
|
||||||
INITBYDIM,
|
INITBYDIM: INITBYDIM as INITBYDIM,
|
||||||
initByDim: INITBYDIM,
|
initByDim: INITBYDIM as INITBYDIM,
|
||||||
INITBYPROB,
|
INITBYPROB: INITBYPROB as INITBYPROB,
|
||||||
initByProb: INITBYPROB,
|
initByProb: INITBYPROB as INITBYPROB,
|
||||||
MERGE,
|
MERGE: MERGE as MERGE,
|
||||||
merge: MERGE,
|
merge: MERGE as MERGE,
|
||||||
QUERY,
|
QUERY: QUERY as QUERY,
|
||||||
query: QUERY
|
query: QUERY as QUERY,
|
||||||
};
|
} satisfies RedisCommands;
|
||||||
|
@@ -1,19 +1,19 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments, transformReply } from './ADD';
|
import ADD from './ADD';
|
||||||
|
|
||||||
describe('CF ADD', () => {
|
describe('CF.ADD', () => {
|
||||||
it('transformArguments', () => {
|
it('transformArguments', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key', 'item'),
|
ADD.transformArguments('key', 'item'),
|
||||||
['CF.ADD', 'key', 'item']
|
['CF.ADD', 'key', 'item']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.cf.add', async client => {
|
testUtils.testWithClient('client.cf.add', async client => {
|
||||||
assert.equal(
|
assert.equal(
|
||||||
await client.cf.add('key', 'item'),
|
await client.cf.add('key', 'item'),
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -1,7 +1,11 @@
|
|||||||
export const FIRST_KEY_INDEX = 1;
|
import { RedisArgument, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
|
import { transformBooleanReply } from '@redis/client/dist/lib/commands/generic-transformers';
|
||||||
|
|
||||||
export function transformArguments(key: string, item: string): Array<string> {
|
export default {
|
||||||
|
FIRST_KEY_INDEX: 1,
|
||||||
|
IS_READ_ONLY: false,
|
||||||
|
transformArguments(key: RedisArgument, item: RedisArgument) {
|
||||||
return ['CF.ADD', key, item];
|
return ['CF.ADD', key, item];
|
||||||
}
|
},
|
||||||
|
transformReply: transformBooleanReply
|
||||||
export { transformBooleanReply as transformReply } from '@redis/client/dist/lib/commands/generic-transformers';
|
} as const satisfies Command;
|
||||||
|
@@ -1,21 +1,19 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './ADDNX';
|
import ADDNX from './ADDNX';
|
||||||
|
|
||||||
describe('CF ADDNX', () => {
|
describe('CF.ADDNX', () => {
|
||||||
describe('transformArguments', () => {
|
it('transformArguments', () => {
|
||||||
it('basic add', () => {
|
assert.deepEqual(
|
||||||
assert.deepEqual(
|
ADDNX.transformArguments('key', 'item'),
|
||||||
transformArguments('key', 'item'),
|
['CF.ADDNX', 'key', 'item']
|
||||||
['CF.ADDNX', 'key', 'item']
|
);
|
||||||
);
|
});
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
testUtils.testWithClient('client.cf.add', async client => {
|
testUtils.testWithClient('client.cf.add', async client => {
|
||||||
assert.equal(
|
assert.equal(
|
||||||
await client.cf.addNX('key', 'item'),
|
await client.cf.addNX('key', 'item'),
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -1,7 +1,11 @@
|
|||||||
export const FIRST_KEY_INDEX = 1;
|
import { RedisArgument, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
|
import { transformBooleanReply } from '@redis/client/dist/lib/commands/generic-transformers';
|
||||||
|
|
||||||
export function transformArguments(key: string, item: string): Array<string> {
|
export default {
|
||||||
|
FIRST_KEY_INDEX: 1,
|
||||||
|
IS_READ_ONLY: false,
|
||||||
|
transformArguments(key: RedisArgument, item: RedisArgument) {
|
||||||
return ['CF.ADDNX', key, item];
|
return ['CF.ADDNX', key, item];
|
||||||
}
|
},
|
||||||
|
transformReply: transformBooleanReply
|
||||||
export { transformBooleanReply as transformReply } from '@redis/client/dist/lib/commands/generic-transformers';
|
} as const satisfies Command;
|
||||||
|
@@ -1,19 +1,19 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './COUNT';
|
import COUNT from './COUNT';
|
||||||
|
|
||||||
describe('CF COUNT', () => {
|
describe('CF.COUNT', () => {
|
||||||
it('transformArguments', () => {
|
it('transformArguments', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key', 'item'),
|
COUNT.transformArguments('key', 'item'),
|
||||||
['CF.COUNT', 'key', 'item']
|
['CF.COUNT', 'key', 'item']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.cf.count', async client => {
|
testUtils.testWithClient('client.cf.count', async client => {
|
||||||
assert.equal(
|
assert.equal(
|
||||||
await client.cf.count('key', 'item'),
|
await client.cf.count('key', 'item'),
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -1,7 +1,10 @@
|
|||||||
export const FIRST_KEY_INDEX = 1;
|
import { RedisArgument, NumberReply, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
|
|
||||||
export function transformArguments(key: string, item: string): Array<string> {
|
export default {
|
||||||
|
FIRST_KEY_INDEX: 1,
|
||||||
|
IS_READ_ONLY: true,
|
||||||
|
transformArguments(key: RedisArgument, item: RedisArgument) {
|
||||||
return ['CF.COUNT', key, item];
|
return ['CF.COUNT', key, item];
|
||||||
}
|
},
|
||||||
|
transformReply: undefined as unknown as () => NumberReply
|
||||||
export declare function transformReply(): number;
|
} as const satisfies Command;
|
||||||
|
@@ -1,21 +1,21 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './DEL';
|
import DEL from './DEL';
|
||||||
|
|
||||||
describe('CF DEL', () => {
|
describe('CF.DEL', () => {
|
||||||
it('transformArguments', () => {
|
it('transformArguments', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key', 'item'),
|
DEL.transformArguments('key', 'item'),
|
||||||
['CF.DEL', 'key', 'item']
|
['CF.DEL', 'key', 'item']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.cf.del', async client => {
|
testUtils.testWithClient('client.cf.del', async client => {
|
||||||
await client.cf.reserve('key', 4);
|
const [, reply] = await Promise.all([
|
||||||
|
client.cf.reserve('key', 4),
|
||||||
|
client.cf.del('key', 'item')
|
||||||
|
]);
|
||||||
|
|
||||||
assert.equal(
|
assert.equal(reply, false);
|
||||||
await client.cf.del('key', 'item'),
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
false
|
|
||||||
);
|
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
|
||||||
});
|
});
|
||||||
|
@@ -1,7 +1,11 @@
|
|||||||
export const FIRST_KEY_INDEX = 1;
|
import { RedisArgument, NumberReply, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
|
import { transformBooleanReply } from '@redis/client/dist/lib/commands/generic-transformers';
|
||||||
|
|
||||||
export function transformArguments(key: string, item: string): Array<string> {
|
export default {
|
||||||
|
FIRST_KEY_INDEX: 1,
|
||||||
|
IS_READ_ONLY: false,
|
||||||
|
transformArguments(key: RedisArgument, item: RedisArgument) {
|
||||||
return ['CF.DEL', key, item];
|
return ['CF.DEL', key, item];
|
||||||
}
|
},
|
||||||
|
transformReply: transformBooleanReply
|
||||||
export { transformBooleanReply as transformReply } from '@redis/client/dist/lib/commands/generic-transformers';
|
} as const satisfies Command;
|
||||||
|
@@ -1,19 +1,19 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './EXISTS';
|
import EXISTS from './EXISTS';
|
||||||
|
|
||||||
describe('CF EXISTS', () => {
|
describe('CF.EXISTS', () => {
|
||||||
it('transformArguments', () => {
|
it('transformArguments', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key', 'item'),
|
EXISTS.transformArguments('key', 'item'),
|
||||||
['CF.EXISTS', 'key', 'item']
|
['CF.EXISTS', 'key', 'item']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.cf.exists', async client => {
|
testUtils.testWithClient('client.cf.exists', async client => {
|
||||||
assert.equal(
|
assert.equal(
|
||||||
await client.cf.exists('key', 'item'),
|
await client.cf.exists('key', 'item'),
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -1,9 +1,11 @@
|
|||||||
export const FIRST_KEY_INDEX = 1;
|
import { RedisArgument, NumberReply, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
|
import { transformBooleanReply } from '@redis/client/dist/lib/commands/generic-transformers';
|
||||||
|
|
||||||
export const IS_READ_ONLY = true;
|
export default {
|
||||||
|
FIRST_KEY_INDEX: 1,
|
||||||
export function transformArguments(key: string, item: string): Array<string> {
|
IS_READ_ONLY: false,
|
||||||
|
transformArguments(key: RedisArgument, item: RedisArgument) {
|
||||||
return ['CF.EXISTS', key, item];
|
return ['CF.EXISTS', key, item];
|
||||||
}
|
},
|
||||||
|
transformReply: transformBooleanReply
|
||||||
export { transformBooleanReply as transformReply } from '@redis/client/dist/lib/commands/generic-transformers';
|
} as const satisfies Command;
|
||||||
|
@@ -1,27 +1,27 @@
|
|||||||
import { strict as assert } from 'assert';
|
// import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
// import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './INFO';
|
// import { transformArguments } from './INFO';
|
||||||
|
|
||||||
describe('CF INFO', () => {
|
// describe('CF INFO', () => {
|
||||||
it('transformArguments', () => {
|
// it('transformArguments', () => {
|
||||||
assert.deepEqual(
|
// assert.deepEqual(
|
||||||
transformArguments('cuckoo'),
|
// transformArguments('cuckoo'),
|
||||||
['CF.INFO', 'cuckoo']
|
// ['CF.INFO', 'cuckoo']
|
||||||
);
|
// );
|
||||||
});
|
// });
|
||||||
|
|
||||||
testUtils.testWithClient('client.cf.info', async client => {
|
// testUtils.testWithClient('client.cf.info', async client => {
|
||||||
await client.cf.reserve('key', 4);
|
// await client.cf.reserve('key', 4);
|
||||||
|
|
||||||
const info = await client.cf.info('key');
|
// const info = await client.cf.info('key');
|
||||||
assert.equal(typeof info, 'object');
|
// assert.equal(typeof info, 'object');
|
||||||
assert.equal(typeof info.size, 'number');
|
// assert.equal(typeof info.size, 'number');
|
||||||
assert.equal(typeof info.numberOfBuckets, 'number');
|
// assert.equal(typeof info.numberOfBuckets, 'number');
|
||||||
assert.equal(typeof info.numberOfFilters, 'number');
|
// assert.equal(typeof info.numberOfFilters, 'number');
|
||||||
assert.equal(typeof info.numberOfInsertedItems, 'number');
|
// assert.equal(typeof info.numberOfInsertedItems, 'number');
|
||||||
assert.equal(typeof info.numberOfDeletedItems, 'number');
|
// assert.equal(typeof info.numberOfDeletedItems, 'number');
|
||||||
assert.equal(typeof info.bucketSize, 'number');
|
// assert.equal(typeof info.bucketSize, 'number');
|
||||||
assert.equal(typeof info.expansionRate, 'number');
|
// assert.equal(typeof info.expansionRate, 'number');
|
||||||
assert.equal(typeof info.maxIteration, 'number');
|
// assert.equal(typeof info.maxIteration, 'number');
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
// }, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
// });
|
||||||
|
@@ -1,50 +1,50 @@
|
|||||||
export const FIRST_KEY_INDEX = 1;
|
// export const FIRST_KEY_INDEX = 1;
|
||||||
|
|
||||||
export const IS_READ_ONLY = true;
|
// export const IS_READ_ONLY = true;
|
||||||
|
|
||||||
export function transformArguments(key: string): Array<string> {
|
// export function transformArguments(key: string): Array<string> {
|
||||||
return ['CF.INFO', key];
|
// return ['CF.INFO', key];
|
||||||
}
|
// }
|
||||||
|
|
||||||
export type InfoRawReply = [
|
// export type InfoRawReply = [
|
||||||
_: string,
|
// _: string,
|
||||||
size: number,
|
// size: number,
|
||||||
_: string,
|
// _: string,
|
||||||
numberOfBuckets: number,
|
// numberOfBuckets: number,
|
||||||
_: string,
|
// _: string,
|
||||||
numberOfFilters: number,
|
// numberOfFilters: number,
|
||||||
_: string,
|
// _: string,
|
||||||
numberOfInsertedItems: number,
|
// numberOfInsertedItems: number,
|
||||||
_: string,
|
// _: string,
|
||||||
numberOfDeletedItems: number,
|
// numberOfDeletedItems: number,
|
||||||
_: string,
|
// _: string,
|
||||||
bucketSize: number,
|
// bucketSize: number,
|
||||||
_: string,
|
// _: string,
|
||||||
expansionRate: number,
|
// expansionRate: number,
|
||||||
_: string,
|
// _: string,
|
||||||
maxIteration: number
|
// maxIteration: number
|
||||||
];
|
// ];
|
||||||
|
|
||||||
export interface InfoReply {
|
// export interface InfoReply {
|
||||||
size: number;
|
// size: number;
|
||||||
numberOfBuckets: number;
|
// numberOfBuckets: number;
|
||||||
numberOfFilters: number;
|
// numberOfFilters: number;
|
||||||
numberOfInsertedItems: number;
|
// numberOfInsertedItems: number;
|
||||||
numberOfDeletedItems: number;
|
// numberOfDeletedItems: number;
|
||||||
bucketSize: number;
|
// bucketSize: number;
|
||||||
expansionRate: number;
|
// expansionRate: number;
|
||||||
maxIteration: number;
|
// maxIteration: number;
|
||||||
}
|
// }
|
||||||
|
|
||||||
export function transformReply(reply: InfoRawReply): InfoReply {
|
// export function transformReply(reply: InfoRawReply): InfoReply {
|
||||||
return {
|
// return {
|
||||||
size: reply[1],
|
// size: reply[1],
|
||||||
numberOfBuckets: reply[3],
|
// numberOfBuckets: reply[3],
|
||||||
numberOfFilters: reply[5],
|
// numberOfFilters: reply[5],
|
||||||
numberOfInsertedItems: reply[7],
|
// numberOfInsertedItems: reply[7],
|
||||||
numberOfDeletedItems: reply[9],
|
// numberOfDeletedItems: reply[9],
|
||||||
bucketSize: reply[11],
|
// bucketSize: reply[11],
|
||||||
expansionRate: reply[13],
|
// expansionRate: reply[13],
|
||||||
maxIteration: reply[15]
|
// maxIteration: reply[15]
|
||||||
};
|
// };
|
||||||
}
|
// }
|
||||||
|
@@ -1,22 +1,22 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './INSERT';
|
import INSERT from './INSERT';
|
||||||
|
|
||||||
describe('CF INSERT', () => {
|
describe('CF.INSERT', () => {
|
||||||
it('transformArguments', () => {
|
it('transformArguments', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key', 'item', {
|
INSERT.transformArguments('key', 'item', {
|
||||||
CAPACITY: 100,
|
CAPACITY: 100,
|
||||||
NOCREATE: true
|
NOCREATE: true
|
||||||
}),
|
}),
|
||||||
['CF.INSERT', 'key', 'CAPACITY', '100', 'NOCREATE', 'ITEMS', 'item']
|
['CF.INSERT', 'key', 'CAPACITY', '100', 'NOCREATE', 'ITEMS', 'item']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.cf.insert', async client => {
|
testUtils.testWithClient('client.cf.insert', async client => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
await client.cf.insert('key', 'item'),
|
await client.cf.insert('key', 'item'),
|
||||||
[true]
|
[true]
|
||||||
);
|
);
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -1,18 +1,34 @@
|
|||||||
import { RedisCommandArguments } from '@redis/client/dist/lib/commands';
|
import { Command, RedisArgument } from '@redis/client/dist/lib/RESP/types';
|
||||||
import { InsertOptions, pushInsertOptions } from ".";
|
import { RedisVariadicArgument, pushVariadicArguments, transformBooleanArrayReply } from '@redis/client/dist/lib/commands/generic-transformers';
|
||||||
|
|
||||||
export const FIRST_KEY_INDEX = 1;
|
export interface CfInsertOptions {
|
||||||
|
CAPACITY?: number;
|
||||||
export function transformArguments(
|
NOCREATE?: boolean;
|
||||||
key: string,
|
|
||||||
items: string | Array<string>,
|
|
||||||
options?: InsertOptions
|
|
||||||
): RedisCommandArguments {
|
|
||||||
return pushInsertOptions(
|
|
||||||
['CF.INSERT', key],
|
|
||||||
items,
|
|
||||||
options
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export { transformBooleanArrayReply as transformReply } from '@redis/client/dist/lib/commands/generic-transformers';
|
export function transofrmCfInsertArguments(
|
||||||
|
command: RedisArgument,
|
||||||
|
key: RedisArgument,
|
||||||
|
items: RedisVariadicArgument,
|
||||||
|
options?: CfInsertOptions
|
||||||
|
) {
|
||||||
|
const args = [command, key];
|
||||||
|
|
||||||
|
if (options?.CAPACITY !== undefined) {
|
||||||
|
args.push('CAPACITY', options.CAPACITY.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options?.NOCREATE) {
|
||||||
|
args.push('NOCREATE');
|
||||||
|
}
|
||||||
|
|
||||||
|
args.push('ITEMS');
|
||||||
|
return pushVariadicArguments(args, items);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
FIRST_KEY_INDEX: 1,
|
||||||
|
IS_READ_ONLY: false,
|
||||||
|
transformArguments: transofrmCfInsertArguments.bind(undefined, 'CF.INSERT'),
|
||||||
|
transformReply: transformBooleanArrayReply
|
||||||
|
} as const satisfies Command;
|
||||||
|
@@ -1,22 +1,22 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './INSERTNX';
|
import INSERTNX from './INSERTNX';
|
||||||
|
|
||||||
describe('CF INSERTNX', () => {
|
describe('CF.INSERTNX', () => {
|
||||||
it('transformArguments', () => {
|
it('transformArguments', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key', 'item', {
|
INSERTNX.transformArguments('key', 'item', {
|
||||||
CAPACITY: 100,
|
CAPACITY: 100,
|
||||||
NOCREATE: true
|
NOCREATE: true
|
||||||
}),
|
}),
|
||||||
['CF.INSERTNX', 'key', 'CAPACITY', '100', 'NOCREATE', 'ITEMS', 'item']
|
['CF.INSERTNX', 'key', 'CAPACITY', '100', 'NOCREATE', 'ITEMS', 'item']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.cf.insertnx', async client => {
|
testUtils.testWithClient('client.cf.insertnx', async client => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
await client.cf.insertNX('key', 'item'),
|
await client.cf.insertNX('key', 'item'),
|
||||||
[true]
|
[true]
|
||||||
);
|
);
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -1,18 +1,9 @@
|
|||||||
import { RedisCommandArguments } from '@redis/client/dist/lib/commands';
|
import { Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
import { InsertOptions, pushInsertOptions } from ".";
|
import INSERT, { transofrmCfInsertArguments } from './INSERT';
|
||||||
|
|
||||||
export const FIRST_KEY_INDEX = 1;
|
export default {
|
||||||
|
FIRST_KEY_INDEX: INSERT.FIRST_KEY_INDEX,
|
||||||
export function transformArguments(
|
IS_READ_ONLY: INSERT.IS_READ_ONLY,
|
||||||
key: string,
|
transformArguments: transofrmCfInsertArguments.bind(undefined, 'CF.INSERTNX'),
|
||||||
items: string | Array<string>,
|
transformReply: INSERT.transformReply
|
||||||
options?: InsertOptions
|
} as const satisfies Command;
|
||||||
): RedisCommandArguments {
|
|
||||||
return pushInsertOptions(
|
|
||||||
['CF.INSERTNX', key],
|
|
||||||
items,
|
|
||||||
options
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export { transformBooleanArrayReply as transformReply } from '@redis/client/dist/lib/commands/generic-transformers';
|
|
||||||
|
@@ -1,31 +1,36 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './LOADCHUNK';
|
import LOADCHUNK from './LOADCHUNK';
|
||||||
|
import { RESP_TYPES } from '@redis/client';
|
||||||
|
|
||||||
describe('CF LOADCHUNK', () => {
|
describe('CF.LOADCHUNK', () => {
|
||||||
it('transformArguments', () => {
|
it('transformArguments', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('item', 0, ''),
|
LOADCHUNK.transformArguments('item', 0, ''),
|
||||||
['CF.LOADCHUNK', 'item', '0', '']
|
['CF.LOADCHUNK', 'item', '0', '']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.cf.loadChunk', async client => {
|
testUtils.testWithClient('client.cf.loadChunk', async client => {
|
||||||
const [,, { iterator, chunk }] = await Promise.all([
|
const [, , { iterator, chunk }] = await Promise.all([
|
||||||
client.cf.reserve('source', 4),
|
client.cf.reserve('source', 4),
|
||||||
client.cf.add('source', 'item'),
|
client.cf.add('source', 'item'),
|
||||||
client.cf.scanDump(
|
client.cf.scanDump('source', 0)
|
||||||
client.commandOptions({ returnBuffers: true }),
|
]);
|
||||||
'source',
|
|
||||||
0
|
|
||||||
)
|
|
||||||
]);
|
|
||||||
|
|
||||||
assert.ok(Buffer.isBuffer(chunk));
|
assert.equal(
|
||||||
|
await client.cf.loadChunk('destination', iterator, chunk),
|
||||||
assert.equal(
|
'OK'
|
||||||
await client.cf.loadChunk('destination', iterator, chunk),
|
);
|
||||||
'OK'
|
}, {
|
||||||
);
|
...GLOBAL.SERVERS.OPEN,
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
clientOptions: {
|
||||||
|
...GLOBAL.SERVERS.OPEN.clientOptions,
|
||||||
|
commandOptions: {
|
||||||
|
typeMapping: {
|
||||||
|
[RESP_TYPES.BLOB_STRING]: Buffer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@@ -1,13 +1,10 @@
|
|||||||
import { RedisCommandArgument, RedisCommandArguments } from '@redis/client/dist/lib/commands';
|
import { SimpleStringReply, Command, RedisArgument } from '@redis/client/dist/lib/RESP/types';
|
||||||
|
|
||||||
export const FIRST_KEY_INDEX = 1;
|
export default {
|
||||||
|
FIRST_KEY_INDEX: 1,
|
||||||
export function transformArguments(
|
IS_READ_ONLY: false,
|
||||||
key: string,
|
transformArguments(key: RedisArgument, iterator: number, chunk: RedisArgument) {
|
||||||
iterator: number,
|
|
||||||
chunk: RedisCommandArgument
|
|
||||||
): RedisCommandArguments {
|
|
||||||
return ['CF.LOADCHUNK', key, iterator.toString(), chunk];
|
return ['CF.LOADCHUNK', key, iterator.toString(), chunk];
|
||||||
}
|
},
|
||||||
|
transformReply: undefined as unknown as () => SimpleStringReply<'OK'>
|
||||||
export declare function transformReply(): 'OK';
|
} as const satisfies Command;
|
||||||
|
@@ -1,48 +1,48 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './RESERVE';
|
import RESERVE from './RESERVE';
|
||||||
|
|
||||||
describe('CF RESERVE', () => {
|
describe('CF.RESERVE', () => {
|
||||||
describe('transformArguments', () => {
|
describe('transformArguments', () => {
|
||||||
it('simple', () => {
|
it('simple', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key', 4),
|
RESERVE.transformArguments('key', 4),
|
||||||
['CF.RESERVE', 'key', '4']
|
['CF.RESERVE', 'key', '4']
|
||||||
);
|
);
|
||||||
});
|
|
||||||
|
|
||||||
it('with EXPANSION', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('key', 4, {
|
|
||||||
EXPANSION: 1
|
|
||||||
}),
|
|
||||||
['CF.RESERVE', 'key', '4', 'EXPANSION', '1']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('with BUCKETSIZE', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('key', 4, {
|
|
||||||
BUCKETSIZE: 2
|
|
||||||
}),
|
|
||||||
['CF.RESERVE', 'key', '4', 'BUCKETSIZE', '2']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('with MAXITERATIONS', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('key', 4, {
|
|
||||||
MAXITERATIONS: 1
|
|
||||||
}),
|
|
||||||
['CF.RESERVE', 'key', '4', 'MAXITERATIONS', '1']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.cf.reserve', async client => {
|
it('with EXPANSION', () => {
|
||||||
assert.equal(
|
assert.deepEqual(
|
||||||
await client.cf.reserve('key', 4),
|
RESERVE.transformArguments('key', 4, {
|
||||||
'OK'
|
EXPANSION: 1
|
||||||
);
|
}),
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
['CF.RESERVE', 'key', '4', 'EXPANSION', '1']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with BUCKETSIZE', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
RESERVE.transformArguments('key', 4, {
|
||||||
|
BUCKETSIZE: 2
|
||||||
|
}),
|
||||||
|
['CF.RESERVE', 'key', '4', 'BUCKETSIZE', '2']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with MAXITERATIONS', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
RESERVE.transformArguments('key', 4, {
|
||||||
|
MAXITERATIONS: 1
|
||||||
|
}),
|
||||||
|
['CF.RESERVE', 'key', '4', 'MAXITERATIONS', '1']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
testUtils.testWithClient('client.cf.reserve', async client => {
|
||||||
|
assert.equal(
|
||||||
|
await client.cf.reserve('key', 4),
|
||||||
|
'OK'
|
||||||
|
);
|
||||||
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -1,31 +1,34 @@
|
|||||||
export const FIRST_KEY_INDEX = 1;
|
import { RedisArgument, SimpleStringReply, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
|
|
||||||
interface ReserveOptions {
|
export interface CfReserveOptions {
|
||||||
BUCKETSIZE?: number;
|
BUCKETSIZE?: number;
|
||||||
MAXITERATIONS?: number;
|
MAXITERATIONS?: number;
|
||||||
EXPANSION?: number;
|
EXPANSION?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function transformArguments(
|
export default {
|
||||||
key: string,
|
FIRST_KEY_INDEX: 1,
|
||||||
|
IS_READ_ONLY: false,
|
||||||
|
transformArguments(
|
||||||
|
key: RedisArgument,
|
||||||
capacity: number,
|
capacity: number,
|
||||||
options?: ReserveOptions
|
options?: CfReserveOptions
|
||||||
): Array<string> {
|
) {
|
||||||
const args = ['CF.RESERVE', key, capacity.toString()];
|
const args = ['CF.RESERVE', key, capacity.toString()];
|
||||||
|
|
||||||
if (options?.BUCKETSIZE) {
|
if (options?.BUCKETSIZE !== undefined) {
|
||||||
args.push('BUCKETSIZE', options.BUCKETSIZE.toString());
|
args.push('BUCKETSIZE', options.BUCKETSIZE.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options?.MAXITERATIONS) {
|
if (options?.MAXITERATIONS !== undefined) {
|
||||||
args.push('MAXITERATIONS', options.MAXITERATIONS.toString());
|
args.push('MAXITERATIONS', options.MAXITERATIONS.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options?.EXPANSION) {
|
if (options?.EXPANSION !== undefined) {
|
||||||
args.push('EXPANSION', options.EXPANSION.toString());
|
args.push('EXPANSION', options.EXPANSION.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return args;
|
return args;
|
||||||
}
|
},
|
||||||
|
transformReply: undefined as unknown as () => SimpleStringReply<'OK'>
|
||||||
export declare function transformReply(): 'OK';
|
} as const satisfies Command;
|
||||||
|
@@ -1,23 +1,24 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './SCANDUMP';
|
import SCANDUMP from './SCANDUMP';
|
||||||
|
|
||||||
describe('CF SCANDUMP', () => {
|
describe('CF.SCANDUMP', () => {
|
||||||
it('transformArguments', () => {
|
it('transformArguments', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key', 0),
|
SCANDUMP.transformArguments('key', 0),
|
||||||
['CF.SCANDUMP', 'key', '0']
|
['CF.SCANDUMP', 'key', '0']
|
||||||
);
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
testUtils.testWithClient('client.cf.scanDump', async client => {
|
||||||
|
const [, reply] = await Promise.all([
|
||||||
|
client.cf.reserve('key', 4),
|
||||||
|
client.cf.scanDump('key', 0)
|
||||||
|
]);
|
||||||
|
|
||||||
|
assert.deepEqual(reply, {
|
||||||
|
iterator: 0,
|
||||||
|
chunk: null
|
||||||
});
|
});
|
||||||
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
testUtils.testWithClient('client.cf.scanDump', async client => {
|
|
||||||
await client.cf.reserve('key', 4);
|
|
||||||
assert.deepEqual(
|
|
||||||
await client.cf.scanDump('key', 0),
|
|
||||||
{
|
|
||||||
iterator: 0,
|
|
||||||
chunk: null
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
|
||||||
});
|
});
|
||||||
|
@@ -1,22 +1,15 @@
|
|||||||
export const FIRST_KEY_INDEX = 1;
|
import { RedisArgument, TuplesReply, NumberReply, BlobStringReply, NullReply, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
|
|
||||||
export function transformArguments(key: string, iterator: number): Array<string> {
|
export default {
|
||||||
|
FIRST_KEY_INDEX: 1,
|
||||||
|
IS_READ_ONLY: true,
|
||||||
|
transformArguments(key: RedisArgument, iterator: number) {
|
||||||
return ['CF.SCANDUMP', key, iterator.toString()];
|
return ['CF.SCANDUMP', key, iterator.toString()];
|
||||||
}
|
},
|
||||||
|
transformReply(reply: TuplesReply<[NumberReply, BlobStringReply | NullReply]>) {
|
||||||
type ScanDumpRawReply = [
|
|
||||||
iterator: number,
|
|
||||||
chunk: string | null
|
|
||||||
];
|
|
||||||
|
|
||||||
interface ScanDumpReply {
|
|
||||||
iterator: number;
|
|
||||||
chunk: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function transformReply([iterator, chunk]: ScanDumpRawReply): ScanDumpReply {
|
|
||||||
return {
|
return {
|
||||||
iterator,
|
iterator: reply[0],
|
||||||
chunk
|
chunk: reply[1]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
} as const satisfies Command;
|
||||||
|
@@ -1,48 +0,0 @@
|
|||||||
import { strict as assert } from 'assert';
|
|
||||||
import { pushInsertOptions } from '.';
|
|
||||||
|
|
||||||
describe('pushInsertOptions', () => {
|
|
||||||
describe('single item', () => {
|
|
||||||
it('single item', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
pushInsertOptions([], 'item'),
|
|
||||||
['ITEMS', 'item']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('multiple items', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
pushInsertOptions([], ['1', '2']),
|
|
||||||
['ITEMS', '1', '2']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('with CAPACITY', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
pushInsertOptions([], 'item', {
|
|
||||||
CAPACITY: 100
|
|
||||||
}),
|
|
||||||
['CAPACITY', '100', 'ITEMS', 'item']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('with NOCREATE', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
pushInsertOptions([], 'item', {
|
|
||||||
NOCREATE: true
|
|
||||||
}),
|
|
||||||
['NOCREATE', 'ITEMS', 'item']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('with CAPACITY and NOCREATE', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
pushInsertOptions([], 'item', {
|
|
||||||
CAPACITY: 100,
|
|
||||||
NOCREATE: true
|
|
||||||
}),
|
|
||||||
['CAPACITY', '100', 'NOCREATE', 'ITEMS', 'item']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
@@ -1,62 +1,48 @@
|
|||||||
|
import ADD from './ADD';
|
||||||
|
import ADDNX from './ADDNX';
|
||||||
|
import COUNT from './COUNT';
|
||||||
|
import DEL from './DEL';
|
||||||
|
import EXISTS from './EXISTS';
|
||||||
|
// import INFO from './INFO';
|
||||||
|
import INSERT from './INSERT';
|
||||||
|
import INSERTNX from './INSERTNX';
|
||||||
|
import LOADCHUNK from './LOADCHUNK';
|
||||||
|
import RESERVE from './RESERVE';
|
||||||
|
import SCANDUMP from './SCANDUMP';
|
||||||
|
|
||||||
import * as ADD from './ADD';
|
type ADD = typeof import('./ADD').default;
|
||||||
import * as ADDNX from './ADDNX';
|
type ADDNX = typeof import('./ADDNX').default;
|
||||||
import * as COUNT from './COUNT';
|
type COUNT = typeof import('./COUNT').default;
|
||||||
import * as DEL from './DEL';
|
type DEL = typeof import('./DEL').default;
|
||||||
import * as EXISTS from './EXISTS';
|
type EXISTS = typeof import('./EXISTS').default;
|
||||||
import * as INFO from './INFO';
|
// type INFO = typeof import('./INFO').default;
|
||||||
import * as INSERT from './INSERT';
|
type INSERT = typeof import('./INSERT').default;
|
||||||
import * as INSERTNX from './INSERTNX';
|
type INSERTNX = typeof import('./INSERTNX').default;
|
||||||
import * as LOADCHUNK from './LOADCHUNK';
|
type LOADCHUNK = typeof import('./LOADCHUNK').default;
|
||||||
import * as RESERVE from './RESERVE';
|
type RESERVE = typeof import('./RESERVE').default;
|
||||||
import * as SCANDUMP from './SCANDUMP';
|
type SCANDUMP = typeof import('./SCANDUMP').default;
|
||||||
import { pushVariadicArguments } from '@redis/client/dist/lib/commands/generic-transformers';
|
|
||||||
import { RedisCommandArguments } from '@redis/client/dist/lib/commands';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
ADD,
|
ADD: ADD as ADD,
|
||||||
add: ADD,
|
add: ADD as ADD,
|
||||||
ADDNX,
|
ADDNX: ADDNX as ADDNX,
|
||||||
addNX: ADDNX,
|
addNX: ADDNX as ADDNX,
|
||||||
COUNT,
|
COUNT: COUNT as COUNT,
|
||||||
count: COUNT,
|
count: COUNT as COUNT,
|
||||||
DEL,
|
DEL: DEL as DEL,
|
||||||
del: DEL,
|
del: DEL as DEL,
|
||||||
EXISTS,
|
EXISTS: EXISTS as EXISTS,
|
||||||
exists: EXISTS,
|
exists: EXISTS as EXISTS,
|
||||||
INFO,
|
// INFO: INFO as INFO,
|
||||||
info: INFO,
|
// info: INFO as INFO,
|
||||||
INSERT,
|
INSERT: INSERT as INSERT,
|
||||||
insert: INSERT,
|
insert: INSERT as INSERT,
|
||||||
INSERTNX,
|
INSERTNX: INSERTNX as INSERTNX,
|
||||||
insertNX: INSERTNX,
|
insertNX: INSERTNX as INSERTNX,
|
||||||
LOADCHUNK,
|
LOADCHUNK: LOADCHUNK as LOADCHUNK,
|
||||||
loadChunk: LOADCHUNK,
|
loadChunk: LOADCHUNK as LOADCHUNK,
|
||||||
RESERVE,
|
RESERVE: RESERVE as RESERVE,
|
||||||
reserve: RESERVE,
|
reserve: RESERVE as RESERVE,
|
||||||
SCANDUMP,
|
SCANDUMP: SCANDUMP as SCANDUMP,
|
||||||
scanDump: SCANDUMP
|
scanDump: SCANDUMP as SCANDUMP
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface InsertOptions {
|
|
||||||
CAPACITY?: number;
|
|
||||||
NOCREATE?: true;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function pushInsertOptions(
|
|
||||||
args: RedisCommandArguments,
|
|
||||||
items: string | Array<string>,
|
|
||||||
options?: InsertOptions
|
|
||||||
): RedisCommandArguments {
|
|
||||||
if (options?.CAPACITY) {
|
|
||||||
args.push('CAPACITY');
|
|
||||||
args.push(options.CAPACITY.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options?.NOCREATE) {
|
|
||||||
args.push('NOCREATE');
|
|
||||||
}
|
|
||||||
|
|
||||||
args.push('ITEMS');
|
|
||||||
return pushVariadicArguments(args, items);
|
|
||||||
}
|
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
import { RedisModules } from '@redis/client';
|
||||||
import bf from './bloom';
|
import bf from './bloom';
|
||||||
import cms from './count-min-sketch';
|
import cms from './count-min-sketch';
|
||||||
import cf from './cuckoo';
|
import cf from './cuckoo';
|
||||||
@@ -5,9 +6,9 @@ import tDigest from './t-digest';
|
|||||||
import topK from './top-k';
|
import topK from './top-k';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
bf,
|
bf,
|
||||||
cms,
|
cms,
|
||||||
cf,
|
cf,
|
||||||
tDigest,
|
tDigest,
|
||||||
topK
|
topK
|
||||||
};
|
} satisfies RedisModules;
|
||||||
|
@@ -1,21 +1,21 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './ADD';
|
import ADD from './ADD';
|
||||||
|
|
||||||
describe('TDIGEST.ADD', () => {
|
describe('TDIGEST.ADD', () => {
|
||||||
it('transformArguments', () => {
|
it('transformArguments', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key', [1, 2]),
|
ADD.transformArguments('key', [1, 2]),
|
||||||
['TDIGEST.ADD', 'key', '1', '2']
|
['TDIGEST.ADD', 'key', '1', '2']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.tDigest.add', async client => {
|
testUtils.testWithClient('client.tDigest.add', async client => {
|
||||||
const [ , reply ] = await Promise.all([
|
const [, reply] = await Promise.all([
|
||||||
client.tDigest.create('key'),
|
client.tDigest.create('key'),
|
||||||
client.tDigest.add('key', [1])
|
client.tDigest.add('key', [1])
|
||||||
]);
|
]);
|
||||||
|
|
||||||
assert.equal(reply, 'OK');
|
assert.equal(reply, 'OK');
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -1,17 +1,16 @@
|
|||||||
import { RedisCommandArgument, RedisCommandArguments } from '@redis/client/dist/lib/commands';
|
import { SimpleStringReply, Command, RedisArgument } from '@redis/client/dist/lib/RESP/types';
|
||||||
|
|
||||||
export const FIRST_KEY_INDEX = 1;
|
export default {
|
||||||
|
FIRST_KEY_INDEX: 1,
|
||||||
export function transformArguments(
|
IS_READ_ONLY: false,
|
||||||
key: RedisCommandArgument,
|
transformArguments(key: RedisArgument, values: Array<number>) {
|
||||||
values: Array<number>
|
|
||||||
): RedisCommandArguments {
|
|
||||||
const args = ['TDIGEST.ADD', key];
|
const args = ['TDIGEST.ADD', key];
|
||||||
for (const item of values) {
|
|
||||||
args.push(item.toString());
|
for (const value of values) {
|
||||||
|
args.push(value.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return args;
|
return args;
|
||||||
}
|
},
|
||||||
|
transformReply: undefined as unknown as () => SimpleStringReply<'OK'>
|
||||||
export declare function transformReply(): 'OK';
|
} as const satisfies Command;
|
||||||
|
@@ -1,21 +1,21 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './BYRANK';
|
import BYRANK from './BYRANK';
|
||||||
|
|
||||||
describe('TDIGEST.BYRANK', () => {
|
describe('TDIGEST.BYRANK', () => {
|
||||||
it('transformArguments', () => {
|
it('transformArguments', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key', [1, 2]),
|
BYRANK.transformArguments('key', [1, 2]),
|
||||||
['TDIGEST.BYRANK', 'key', '1', '2']
|
['TDIGEST.BYRANK', 'key', '1', '2']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.tDigest.byRank', async client => {
|
testUtils.testWithClient('client.tDigest.byRank', async client => {
|
||||||
const [ , reply ] = await Promise.all([
|
const [, reply] = await Promise.all([
|
||||||
client.tDigest.create('key'),
|
client.tDigest.create('key'),
|
||||||
client.tDigest.byRank('key', [1])
|
client.tDigest.byRank('key', [1])
|
||||||
]);
|
]);
|
||||||
|
|
||||||
assert.deepEqual(reply, [NaN]);
|
assert.deepEqual(reply, [NaN]);
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -1,19 +1,24 @@
|
|||||||
import { RedisCommandArgument, RedisCommandArguments } from '@redis/client/dist/lib/commands';
|
import { RedisArgument, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
|
import { transformArrayDoubleReply } from '@redis/client/dist/lib/commands/generic-transformers';
|
||||||
|
|
||||||
export const FIRST_KEY_INDEX = 1;
|
export function transformByRankArguments(
|
||||||
|
command: RedisArgument,
|
||||||
|
key: RedisArgument,
|
||||||
|
ranks: Array<number>
|
||||||
|
) {
|
||||||
|
const args = [command, key];
|
||||||
|
|
||||||
export const IS_READ_ONLY = true;
|
for (const rank of ranks) {
|
||||||
|
args.push(rank.toString());
|
||||||
|
}
|
||||||
|
|
||||||
export function transformArguments(
|
return args;
|
||||||
key: RedisCommandArgument,
|
|
||||||
ranks: Array<number>
|
|
||||||
): RedisCommandArguments {
|
|
||||||
const args = ['TDIGEST.BYRANK', key];
|
|
||||||
for (const rank of ranks) {
|
|
||||||
args.push(rank.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
return args;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export { transformDoublesReply as transformReply } from '.';
|
export default {
|
||||||
|
FIRST_KEY_INDEX: 1,
|
||||||
|
IS_READ_ONLY: true,
|
||||||
|
transformArguments: transformByRankArguments.bind(undefined, 'TDIGEST.BYRANK'),
|
||||||
|
transformReply: transformArrayDoubleReply
|
||||||
|
} as const satisfies Command;
|
||||||
|
|
||||||
|
@@ -1,21 +1,21 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './BYREVRANK';
|
import BYREVRANK from './BYREVRANK';
|
||||||
|
|
||||||
describe('TDIGEST.BYREVRANK', () => {
|
describe('TDIGEST.BYREVRANK', () => {
|
||||||
it('transformArguments', () => {
|
it('transformArguments', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key', [1, 2]),
|
BYREVRANK.transformArguments('key', [1, 2]),
|
||||||
['TDIGEST.BYREVRANK', 'key', '1', '2']
|
['TDIGEST.BYREVRANK', 'key', '1', '2']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.tDigest.byRevRank', async client => {
|
testUtils.testWithClient('client.tDigest.byRevRank', async client => {
|
||||||
const [ , reply ] = await Promise.all([
|
const [, reply] = await Promise.all([
|
||||||
client.tDigest.create('key'),
|
client.tDigest.create('key'),
|
||||||
client.tDigest.byRevRank('key', [1])
|
client.tDigest.byRevRank('key', [1])
|
||||||
]);
|
]);
|
||||||
|
|
||||||
assert.deepEqual(reply, [NaN]);
|
assert.deepEqual(reply, [NaN]);
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -1,19 +1,9 @@
|
|||||||
import { RedisCommandArgument, RedisCommandArguments } from '@redis/client/dist/lib/commands';
|
import { Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
|
import BYRANK, { transformByRankArguments } from './BYRANK';
|
||||||
|
|
||||||
export const FIRST_KEY_INDEX = 1;
|
export default {
|
||||||
|
FIRST_KEY_INDEX: BYRANK.FIRST_KEY_INDEX,
|
||||||
export const IS_READ_ONLY = true;
|
IS_READ_ONLY: BYRANK.IS_READ_ONLY,
|
||||||
|
transformArguments: transformByRankArguments.bind(undefined, 'TDIGEST.BYREVRANK'),
|
||||||
export function transformArguments(
|
transformReply: BYRANK.transformReply
|
||||||
key: RedisCommandArgument,
|
} as const satisfies Command;
|
||||||
ranks: Array<number>
|
|
||||||
): RedisCommandArguments {
|
|
||||||
const args = ['TDIGEST.BYREVRANK', key];
|
|
||||||
for (const rank of ranks) {
|
|
||||||
args.push(rank.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
return args;
|
|
||||||
}
|
|
||||||
|
|
||||||
export { transformDoublesReply as transformReply } from '.';
|
|
||||||
|
@@ -1,21 +1,21 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './CDF';
|
import CDF from './CDF';
|
||||||
|
|
||||||
describe('TDIGEST.CDF', () => {
|
describe('TDIGEST.CDF', () => {
|
||||||
it('transformArguments', () => {
|
it('transformArguments', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key', [1, 2]),
|
CDF.transformArguments('key', [1, 2]),
|
||||||
['TDIGEST.CDF', 'key', '1', '2']
|
['TDIGEST.CDF', 'key', '1', '2']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.tDigest.cdf', async client => {
|
testUtils.testWithClient('client.tDigest.cdf', async client => {
|
||||||
const [ , reply ] = await Promise.all([
|
const [, reply] = await Promise.all([
|
||||||
client.tDigest.create('key'),
|
client.tDigest.create('key'),
|
||||||
client.tDigest.cdf('key', [1])
|
client.tDigest.cdf('key', [1])
|
||||||
]);
|
]);
|
||||||
|
|
||||||
assert.deepEqual(reply, [NaN]);
|
assert.deepEqual(reply, [NaN]);
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -1,19 +1,17 @@
|
|||||||
import { RedisCommandArgument, RedisCommandArguments } from '@redis/client/dist/lib/commands';
|
import { RedisArgument, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
|
import { transformArrayDoubleReply } from '@redis/client/dist/lib/commands/generic-transformers';
|
||||||
|
|
||||||
export const FIRST_KEY_INDEX = 1;
|
export default {
|
||||||
|
FIRST_KEY_INDEX: 1,
|
||||||
export const IS_READ_ONLY = true;
|
IS_READ_ONLY: true,
|
||||||
|
transformArguments(key: RedisArgument, values: Array<number>) {
|
||||||
export function transformArguments(
|
|
||||||
key: RedisCommandArgument,
|
|
||||||
values: Array<number>
|
|
||||||
): RedisCommandArguments {
|
|
||||||
const args = ['TDIGEST.CDF', key];
|
const args = ['TDIGEST.CDF', key];
|
||||||
|
|
||||||
for (const item of values) {
|
for (const item of values) {
|
||||||
args.push(item.toString());
|
args.push(item.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return args;
|
return args;
|
||||||
}
|
},
|
||||||
|
transformReply: transformArrayDoubleReply
|
||||||
export { transformDoublesReply as transformReply } from '.';
|
} as const satisfies Command;
|
||||||
|
@@ -1,30 +1,30 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './CREATE';
|
import CREATE from './CREATE';
|
||||||
|
|
||||||
describe('TDIGEST.CREATE', () => {
|
describe('TDIGEST.CREATE', () => {
|
||||||
describe('transformArguments', () => {
|
describe('transformArguments', () => {
|
||||||
it('without options', () => {
|
it('without options', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key'),
|
CREATE.transformArguments('key'),
|
||||||
['TDIGEST.CREATE', 'key']
|
['TDIGEST.CREATE', 'key']
|
||||||
);
|
);
|
||||||
});
|
|
||||||
|
|
||||||
it('with COMPRESSION', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('key', {
|
|
||||||
COMPRESSION: 100
|
|
||||||
}),
|
|
||||||
['TDIGEST.CREATE', 'key', 'COMPRESSION', '100']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.tDigest.create', async client => {
|
it('with COMPRESSION', () => {
|
||||||
assert.equal(
|
assert.deepEqual(
|
||||||
await client.tDigest.create('key'),
|
CREATE.transformArguments('key', {
|
||||||
'OK'
|
COMPRESSION: 100
|
||||||
);
|
}),
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
['TDIGEST.CREATE', 'key', 'COMPRESSION', '100']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
testUtils.testWithClient('client.tDigest.create', async client => {
|
||||||
|
assert.equal(
|
||||||
|
await client.tDigest.create('key'),
|
||||||
|
'OK'
|
||||||
|
);
|
||||||
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -1,16 +1,20 @@
|
|||||||
import { RedisCommandArgument, RedisCommandArguments } from '@redis/client/dist/lib/commands';
|
import { RedisArgument, SimpleStringReply, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
import { CompressionOption, pushCompressionArgument } from '.';
|
|
||||||
|
|
||||||
export const FIRST_KEY_INDEX = 1;
|
export interface TDigestCreateOptions {
|
||||||
|
COMPRESSION?: number;
|
||||||
export function transformArguments(
|
|
||||||
key: RedisCommandArgument,
|
|
||||||
options?: CompressionOption
|
|
||||||
): RedisCommandArguments {
|
|
||||||
return pushCompressionArgument(
|
|
||||||
['TDIGEST.CREATE', key],
|
|
||||||
options
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export declare function transformReply(): 'OK';
|
export default {
|
||||||
|
FIRST_KEY_INDEX: 1,
|
||||||
|
IS_READ_ONLY: false,
|
||||||
|
transformArguments(key: RedisArgument, options?: TDigestCreateOptions) {
|
||||||
|
const args = ['TDIGEST.CREATE', key];
|
||||||
|
|
||||||
|
if (options?.COMPRESSION !== undefined) {
|
||||||
|
args.push('COMPRESSION', options.COMPRESSION.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return args;
|
||||||
|
},
|
||||||
|
transformReply: undefined as unknown as () => SimpleStringReply<'OK'>
|
||||||
|
} as const satisfies Command;
|
||||||
|
@@ -1,25 +1,25 @@
|
|||||||
import { strict as assert } from 'assert';
|
// import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
// import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './INFO';
|
// import { transformArguments } from './INFO';
|
||||||
|
|
||||||
describe('TDIGEST.INFO', () => {
|
// describe('TDIGEST.INFO', () => {
|
||||||
it('transformArguments', () => {
|
// it('transformArguments', () => {
|
||||||
assert.deepEqual(
|
// assert.deepEqual(
|
||||||
transformArguments('key'),
|
// transformArguments('key'),
|
||||||
['TDIGEST.INFO', 'key']
|
// ['TDIGEST.INFO', 'key']
|
||||||
);
|
// );
|
||||||
});
|
// });
|
||||||
|
|
||||||
testUtils.testWithClient('client.tDigest.info', async client => {
|
// testUtils.testWithClient('client.tDigest.info', async client => {
|
||||||
await client.tDigest.create('key');
|
// await client.tDigest.create('key');
|
||||||
|
|
||||||
const info = await client.tDigest.info('key');
|
// const info = await client.tDigest.info('key');
|
||||||
assert(typeof info.capacity, 'number');
|
// assert(typeof info.capacity, 'number');
|
||||||
assert(typeof info.mergedNodes, 'number');
|
// assert(typeof info.mergedNodes, 'number');
|
||||||
assert(typeof info.unmergedNodes, 'number');
|
// assert(typeof info.unmergedNodes, 'number');
|
||||||
assert(typeof info.mergedWeight, 'number');
|
// assert(typeof info.mergedWeight, 'number');
|
||||||
assert(typeof info.unmergedWeight, 'number');
|
// assert(typeof info.unmergedWeight, 'number');
|
||||||
assert(typeof info.totalCompression, 'number');
|
// assert(typeof info.totalCompression, 'number');
|
||||||
assert(typeof info.totalCompression, 'number');
|
// assert(typeof info.totalCompression, 'number');
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
// }, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
// });
|
||||||
|
@@ -1,51 +1,51 @@
|
|||||||
import { RedisCommandArgument, RedisCommandArguments } from '@redis/client/dist/lib/commands';
|
// import { RedisCommandArgument, RedisCommandArguments } from '@redis/client/dist/lib/commands';
|
||||||
|
|
||||||
export const FIRST_KEY_INDEX = 1;
|
// export const FIRST_KEY_INDEX = 1;
|
||||||
|
|
||||||
export const IS_READ_ONLY = true;
|
// export const IS_READ_ONLY = true;
|
||||||
|
|
||||||
export function transformArguments(key: RedisCommandArgument): RedisCommandArguments {
|
// export function transformArguments(key: RedisCommandArgument): RedisCommandArguments {
|
||||||
return [
|
// return [
|
||||||
'TDIGEST.INFO',
|
// 'TDIGEST.INFO',
|
||||||
key
|
// key
|
||||||
];
|
// ];
|
||||||
}
|
// }
|
||||||
|
|
||||||
type InfoRawReply = [
|
// type InfoRawReply = [
|
||||||
'Compression',
|
// 'Compression',
|
||||||
number,
|
// number,
|
||||||
'Capacity',
|
// 'Capacity',
|
||||||
number,
|
// number,
|
||||||
'Merged nodes',
|
// 'Merged nodes',
|
||||||
number,
|
// number,
|
||||||
'Unmerged nodes',
|
// 'Unmerged nodes',
|
||||||
number,
|
// number,
|
||||||
'Merged weight',
|
// 'Merged weight',
|
||||||
string,
|
// string,
|
||||||
'Unmerged weight',
|
// 'Unmerged weight',
|
||||||
string,
|
// string,
|
||||||
'Total compressions',
|
// 'Total compressions',
|
||||||
number
|
// number
|
||||||
];
|
// ];
|
||||||
|
|
||||||
interface InfoReply {
|
// interface InfoReply {
|
||||||
comperssion: number;
|
// comperssion: number;
|
||||||
capacity: number;
|
// capacity: number;
|
||||||
mergedNodes: number;
|
// mergedNodes: number;
|
||||||
unmergedNodes: number;
|
// unmergedNodes: number;
|
||||||
mergedWeight: number;
|
// mergedWeight: number;
|
||||||
unmergedWeight: number;
|
// unmergedWeight: number;
|
||||||
totalCompression: number;
|
// totalCompression: number;
|
||||||
}
|
// }
|
||||||
|
|
||||||
export function transformReply(reply: InfoRawReply): InfoReply {
|
// export function transformReply(reply: InfoRawReply): InfoReply {
|
||||||
return {
|
// return {
|
||||||
comperssion: reply[1],
|
// comperssion: reply[1],
|
||||||
capacity: reply[3],
|
// capacity: reply[3],
|
||||||
mergedNodes: reply[5],
|
// mergedNodes: reply[5],
|
||||||
unmergedNodes: reply[7],
|
// unmergedNodes: reply[7],
|
||||||
mergedWeight: Number(reply[9]),
|
// mergedWeight: Number(reply[9]),
|
||||||
unmergedWeight: Number(reply[11]),
|
// unmergedWeight: Number(reply[11]),
|
||||||
totalCompression: reply[13]
|
// totalCompression: reply[13]
|
||||||
};
|
// };
|
||||||
}
|
// }
|
@@ -1,21 +1,21 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments, transformReply } from './MAX';
|
import MAX from './MAX';
|
||||||
|
|
||||||
describe('TDIGEST.MAX', () => {
|
describe('TDIGEST.MAX', () => {
|
||||||
it('transformArguments', () => {
|
it('transformArguments', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key'),
|
MAX.transformArguments('key'),
|
||||||
['TDIGEST.MAX', 'key']
|
['TDIGEST.MAX', 'key']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.tDigest.max', async client => {
|
testUtils.testWithClient('client.tDigest.max', async client => {
|
||||||
const [ , reply ] = await Promise.all([
|
const [, reply] = await Promise.all([
|
||||||
client.tDigest.create('key'),
|
client.tDigest.create('key'),
|
||||||
client.tDigest.max('key')
|
client.tDigest.max('key')
|
||||||
]);
|
]);
|
||||||
|
|
||||||
assert.deepEqual(reply, NaN);
|
assert.deepEqual(reply, NaN);
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -1,14 +1,11 @@
|
|||||||
import { RedisCommandArgument, RedisCommandArguments } from '@redis/client/dist/lib/commands';
|
import { RedisArgument, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
|
import { transformDoubleReply } from '@redis/client/dist/lib/commands/generic-transformers';
|
||||||
|
|
||||||
export const FIRST_KEY_INDEX = 1;
|
export default {
|
||||||
|
FIRST_KEY_INDEX: 1,
|
||||||
export const IS_READ_ONLY = true;
|
IS_READ_ONLY: true,
|
||||||
|
transformArguments(key: RedisArgument) {
|
||||||
export function transformArguments(key: RedisCommandArgument): RedisCommandArguments {
|
return ['TDIGEST.MAX', key];
|
||||||
return [
|
},
|
||||||
'TDIGEST.MAX',
|
transformReply: transformDoubleReply
|
||||||
key
|
} as const satisfies Command;
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
export { transformDoubleReply as transformReply } from '.';
|
|
||||||
|
@@ -1,50 +1,50 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments, transformReply } from './MERGE';
|
import MERGE from './MERGE';
|
||||||
|
|
||||||
describe('TDIGEST.MERGE', () => {
|
describe('TDIGEST.MERGE', () => {
|
||||||
describe('transformArguments', () => {
|
describe('transformArguments', () => {
|
||||||
describe('srcKeys', () => {
|
describe('source', () => {
|
||||||
it('string', () => {
|
it('string', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('dest', 'src'),
|
MERGE.transformArguments('destination', 'source'),
|
||||||
['TDIGEST.MERGE', 'dest', '1', 'src']
|
['TDIGEST.MERGE', 'destination', '1', 'source']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Array', () => {
|
it('Array', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('dest', ['1', '2']),
|
MERGE.transformArguments('destination', ['1', '2']),
|
||||||
['TDIGEST.MERGE', 'dest', '2', '1', '2']
|
['TDIGEST.MERGE', 'destination', '2', '1', '2']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
it('with COMPRESSION', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('dest', 'src', {
|
|
||||||
COMPRESSION: 100
|
|
||||||
}),
|
|
||||||
['TDIGEST.MERGE', 'dest', '1', 'src', 'COMPRESSION', '100']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('with OVERRIDE', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('dest', 'src', {
|
|
||||||
OVERRIDE: true
|
|
||||||
}),
|
|
||||||
['TDIGEST.MERGE', 'dest', '1', 'src', 'OVERRIDE']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.tDigest.merge', async client => {
|
it('with COMPRESSION', () => {
|
||||||
const [ , reply ] = await Promise.all([
|
assert.deepEqual(
|
||||||
client.tDigest.create('src'),
|
MERGE.transformArguments('destination', 'source', {
|
||||||
client.tDigest.merge('dest', 'src')
|
COMPRESSION: 100
|
||||||
]);
|
}),
|
||||||
|
['TDIGEST.MERGE', 'destination', '1', 'source', 'COMPRESSION', '100']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
assert.equal(reply, 'OK');
|
it('with OVERRIDE', () => {
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
assert.deepEqual(
|
||||||
|
MERGE.transformArguments('destination', 'source', {
|
||||||
|
OVERRIDE: true
|
||||||
|
}),
|
||||||
|
['TDIGEST.MERGE', 'destination', '1', 'source', 'OVERRIDE']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
testUtils.testWithClient('client.tDigest.merge', async client => {
|
||||||
|
const [, reply] = await Promise.all([
|
||||||
|
client.tDigest.create('source'),
|
||||||
|
client.tDigest.merge('destination', 'source')
|
||||||
|
]);
|
||||||
|
|
||||||
|
assert.equal(reply, 'OK');
|
||||||
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -1,30 +1,30 @@
|
|||||||
import { RedisCommandArgument, RedisCommandArguments } from '@redis/client/dist/lib/commands';
|
import { RedisArgument, SimpleStringReply, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
import { pushVariadicArgument } from '@redis/client/dist/lib/commands/generic-transformers';
|
import { RedisVariadicArgument, pushVariadicArgument } from '@redis/client/dist/lib/commands/generic-transformers';
|
||||||
import { CompressionOption, pushCompressionArgument } from '.';
|
|
||||||
|
|
||||||
export const FIRST_KEY_INDEX = 1;
|
export interface TDigestMergeOptions {
|
||||||
|
COMPRESSION?: number;
|
||||||
interface MergeOptions extends CompressionOption {
|
OVERRIDE?: boolean;
|
||||||
OVERRIDE?: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function transformArguments(
|
export default {
|
||||||
destKey: RedisCommandArgument,
|
FIRST_KEY_INDEX: undefined,
|
||||||
srcKeys: RedisCommandArgument | Array<RedisCommandArgument>,
|
IS_READ_ONLY: false,
|
||||||
options?: MergeOptions
|
transformArguments(
|
||||||
): RedisCommandArguments {
|
destination: RedisArgument,
|
||||||
const args = pushVariadicArgument(
|
source: RedisVariadicArgument,
|
||||||
['TDIGEST.MERGE', destKey],
|
options?: TDigestMergeOptions
|
||||||
srcKeys
|
) {
|
||||||
);
|
const args = pushVariadicArgument(['TDIGEST.MERGE', destination], source);
|
||||||
|
|
||||||
pushCompressionArgument(args, options);
|
if (options?.COMPRESSION !== undefined) {
|
||||||
|
args.push('COMPRESSION', options.COMPRESSION.toString());
|
||||||
|
}
|
||||||
|
|
||||||
if (options?.OVERRIDE) {
|
if (options?.OVERRIDE) {
|
||||||
args.push('OVERRIDE');
|
args.push('OVERRIDE');
|
||||||
}
|
}
|
||||||
|
|
||||||
return args;
|
return args;
|
||||||
}
|
},
|
||||||
|
transformReply: undefined as unknown as () => SimpleStringReply<'OK'>
|
||||||
export declare function transformReply(): 'OK';
|
} as const satisfies Command;
|
||||||
|
@@ -1,21 +1,21 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments, transformReply } from './MIN';
|
import MIN from './MIN';
|
||||||
|
|
||||||
describe('TDIGEST.MIN', () => {
|
describe('TDIGEST.MIN', () => {
|
||||||
it('transformArguments', () => {
|
it('transformArguments', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key'),
|
MIN.transformArguments('key'),
|
||||||
['TDIGEST.MIN', 'key']
|
['TDIGEST.MIN', 'key']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.tDigest.min', async client => {
|
testUtils.testWithClient('client.tDigest.min', async client => {
|
||||||
const [ , reply ] = await Promise.all([
|
const [, reply] = await Promise.all([
|
||||||
client.tDigest.create('key'),
|
client.tDigest.create('key'),
|
||||||
client.tDigest.min('key')
|
client.tDigest.min('key')
|
||||||
]);
|
]);
|
||||||
|
|
||||||
assert.equal(reply, NaN);
|
assert.equal(reply, NaN);
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -1,14 +1,11 @@
|
|||||||
import { RedisCommandArgument, RedisCommandArguments } from '@redis/client/dist/lib/commands';
|
import { RedisArgument, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
|
import { transformDoubleReply } from '@redis/client/dist/lib/commands/generic-transformers';
|
||||||
|
|
||||||
export const FIRST_KEY_INDEX = 1;
|
export default {
|
||||||
|
FIRST_KEY_INDEX: 1,
|
||||||
export const IS_READ_ONLY = true;
|
IS_READ_ONLY: true,
|
||||||
|
transformArguments(key: RedisArgument) {
|
||||||
export function transformArguments(key: RedisCommandArgument): RedisCommandArguments {
|
return ['TDIGEST.MIN', key];
|
||||||
return [
|
},
|
||||||
'TDIGEST.MIN',
|
transformReply: transformDoubleReply
|
||||||
key
|
} as const satisfies Command;
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
export { transformDoubleReply as transformReply } from '.';
|
|
||||||
|
@@ -1,24 +1,24 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './QUANTILE';
|
import QUANTILE from './QUANTILE';
|
||||||
|
|
||||||
describe('TDIGEST.QUANTILE', () => {
|
describe('TDIGEST.QUANTILE', () => {
|
||||||
it('transformArguments', () => {
|
it('transformArguments', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key', [1, 2]),
|
QUANTILE.transformArguments('key', [1, 2]),
|
||||||
['TDIGEST.QUANTILE', 'key', '1', '2']
|
['TDIGEST.QUANTILE', 'key', '1', '2']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.tDigest.quantile', async client => {
|
testUtils.testWithClient('client.tDigest.quantile', async client => {
|
||||||
const [, reply] = await Promise.all([
|
const [, reply] = await Promise.all([
|
||||||
client.tDigest.create('key'),
|
client.tDigest.create('key'),
|
||||||
client.tDigest.quantile('key', [1])
|
client.tDigest.quantile('key', [1])
|
||||||
]);
|
]);
|
||||||
|
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
reply,
|
reply,
|
||||||
[NaN]
|
[NaN]
|
||||||
);
|
);
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -1,23 +1,17 @@
|
|||||||
import { RedisCommandArgument, RedisCommandArguments } from '@redis/client/dist/lib/commands';
|
import { RedisArgument, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
|
import { transformArrayDoubleReply } from '@redis/client/dist/lib/commands/generic-transformers';
|
||||||
|
|
||||||
export const FIRST_KEY_INDEX = 1;
|
export default {
|
||||||
|
FIRST_KEY_INDEX: 1,
|
||||||
export const IS_READ_ONLY = true;
|
IS_READ_ONLY: true,
|
||||||
|
transformArguments(key: RedisArgument, quantiles: Array<number>) {
|
||||||
export function transformArguments(
|
const args = ['TDIGEST.QUANTILE', key];
|
||||||
key: RedisCommandArgument,
|
|
||||||
quantiles: Array<number>
|
|
||||||
): RedisCommandArguments {
|
|
||||||
const args = [
|
|
||||||
'TDIGEST.QUANTILE',
|
|
||||||
key
|
|
||||||
];
|
|
||||||
|
|
||||||
for (const quantile of quantiles) {
|
for (const quantile of quantiles) {
|
||||||
args.push(quantile.toString());
|
args.push(quantile.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return args;
|
return args;
|
||||||
}
|
},
|
||||||
|
transformReply: transformArrayDoubleReply
|
||||||
export { transformDoublesReply as transformReply } from '.';
|
} as const satisfies Command;
|
||||||
|
@@ -1,21 +1,21 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './RANK';
|
import RANK from './RANK';
|
||||||
|
|
||||||
describe('TDIGEST.RANK', () => {
|
describe('TDIGEST.RANK', () => {
|
||||||
it('transformArguments', () => {
|
it('transformArguments', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key', [1, 2]),
|
RANK.transformArguments('key', [1, 2]),
|
||||||
['TDIGEST.RANK', 'key', '1', '2']
|
['TDIGEST.RANK', 'key', '1', '2']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.tDigest.rank', async client => {
|
testUtils.testWithClient('client.tDigest.rank', async client => {
|
||||||
const [ , reply ] = await Promise.all([
|
const [, reply] = await Promise.all([
|
||||||
client.tDigest.create('key'),
|
client.tDigest.create('key'),
|
||||||
client.tDigest.rank('key', [1])
|
client.tDigest.rank('key', [1])
|
||||||
]);
|
]);
|
||||||
|
|
||||||
assert.deepEqual(reply, [-2]);
|
assert.deepEqual(reply, [-2]);
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -1,19 +1,22 @@
|
|||||||
import { RedisCommandArgument, RedisCommandArguments } from '@redis/client/dist/lib/commands';
|
import { RedisArgument, ArrayReply, NumberReply, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
|
|
||||||
export const FIRST_KEY_INDEX = 1;
|
export function transformRankArguments(
|
||||||
|
command: RedisArgument,
|
||||||
|
key: RedisArgument,
|
||||||
|
values: Array<number>
|
||||||
|
) {
|
||||||
|
const args = [command, key];
|
||||||
|
|
||||||
export const IS_READ_ONLY = true;
|
for (const value of values) {
|
||||||
|
args.push(value.toString());
|
||||||
|
}
|
||||||
|
|
||||||
export function transformArguments(
|
return args;
|
||||||
key: RedisCommandArgument,
|
|
||||||
values: Array<number>
|
|
||||||
): RedisCommandArguments {
|
|
||||||
const args = ['TDIGEST.RANK', key];
|
|
||||||
for (const item of values) {
|
|
||||||
args.push(item.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
return args;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export declare function transformReply(): Array<number>;
|
export default {
|
||||||
|
FIRST_KEY_INDEX: 1,
|
||||||
|
IS_READ_ONLY: true,
|
||||||
|
transformArguments: transformRankArguments.bind(undefined, 'TDIGEST.RANK'),
|
||||||
|
transformReply: undefined as unknown as () => ArrayReply<NumberReply>
|
||||||
|
} as const satisfies Command;
|
||||||
|
@@ -1,21 +1,21 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './RESET';
|
import RESET from './RESET';
|
||||||
|
|
||||||
describe('TDIGEST.RESET', () => {
|
describe('TDIGEST.RESET', () => {
|
||||||
it('transformArguments', () => {
|
it('transformArguments', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key'),
|
RESET.transformArguments('key'),
|
||||||
['TDIGEST.RESET', 'key']
|
['TDIGEST.RESET', 'key']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.tDigest.reset', async client => {
|
testUtils.testWithClient('client.tDigest.reset', async client => {
|
||||||
const [, reply] = await Promise.all([
|
const [, reply] = await Promise.all([
|
||||||
client.tDigest.create('key'),
|
client.tDigest.create('key'),
|
||||||
client.tDigest.reset('key')
|
client.tDigest.reset('key')
|
||||||
]);
|
]);
|
||||||
|
|
||||||
assert.equal(reply, 'OK');
|
assert.equal(reply, 'OK');
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -1,9 +1,10 @@
|
|||||||
import { RedisCommandArgument, RedisCommandArguments } from '@redis/client/dist/lib/commands';
|
import { RedisArgument, SimpleStringReply, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
|
|
||||||
export const FIRST_KEY_INDEX = 1;
|
export default {
|
||||||
|
FIRST_KEY_INDEX: 1,
|
||||||
export function transformArguments(key: RedisCommandArgument): RedisCommandArguments {
|
IS_READ_ONLY: false,
|
||||||
|
transformArguments(key: RedisArgument) {
|
||||||
return ['TDIGEST.RESET', key];
|
return ['TDIGEST.RESET', key];
|
||||||
}
|
},
|
||||||
|
transformReply: undefined as unknown as () => SimpleStringReply<'OK'>
|
||||||
export declare function transformReply(): 'OK';
|
} as const satisfies Command;
|
||||||
|
@@ -1,21 +1,21 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './REVRANK';
|
import REVRANK from './REVRANK';
|
||||||
|
|
||||||
describe('TDIGEST.REVRANK', () => {
|
describe('TDIGEST.REVRANK', () => {
|
||||||
it('transformArguments', () => {
|
it('transformArguments', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key', [1, 2]),
|
REVRANK.transformArguments('key', [1, 2]),
|
||||||
['TDIGEST.REVRANK', 'key', '1', '2']
|
['TDIGEST.REVRANK', 'key', '1', '2']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.tDigest.revRank', async client => {
|
testUtils.testWithClient('client.tDigest.revRank', async client => {
|
||||||
const [ , reply ] = await Promise.all([
|
const [, reply] = await Promise.all([
|
||||||
client.tDigest.create('key'),
|
client.tDigest.create('key'),
|
||||||
client.tDigest.revRank('key', [1])
|
client.tDigest.revRank('key', [1])
|
||||||
]);
|
]);
|
||||||
|
|
||||||
assert.deepEqual(reply, [-2]);
|
assert.deepEqual(reply, [-2]);
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -1,19 +1,9 @@
|
|||||||
import { RedisCommandArgument, RedisCommandArguments } from '@redis/client/dist/lib/commands';
|
import { Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
|
import RANK, { transformRankArguments } from './RANK';
|
||||||
|
|
||||||
export const FIRST_KEY_INDEX = 1;
|
export default {
|
||||||
|
FIRST_KEY_INDEX: RANK.FIRST_KEY_INDEX,
|
||||||
export const IS_READ_ONLY = true;
|
IS_READ_ONLY: RANK.IS_READ_ONLY,
|
||||||
|
transformArguments: transformRankArguments.bind(undefined, 'TDIGEST.REVRANK'),
|
||||||
export function transformArguments(
|
transformReply: RANK.transformReply
|
||||||
key: RedisCommandArgument,
|
} as const satisfies Command;
|
||||||
values: Array<number>
|
|
||||||
): RedisCommandArguments {
|
|
||||||
const args = ['TDIGEST.REVRANK', key];
|
|
||||||
for (const item of values) {
|
|
||||||
args.push(item.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
return args;
|
|
||||||
}
|
|
||||||
|
|
||||||
export declare function transformReply(): Array<number>;
|
|
||||||
|
@@ -1,21 +1,21 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments, transformReply } from './TRIMMED_MEAN';
|
import TRIMMED_MEAN from './TRIMMED_MEAN';
|
||||||
|
|
||||||
describe('TDIGEST.RESET', () => {
|
describe('TDIGEST.TRIMMED_MEAN', () => {
|
||||||
it('transformArguments', () => {
|
it('transformArguments', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key', 0, 1),
|
TRIMMED_MEAN.transformArguments('key', 0, 1),
|
||||||
['TDIGEST.TRIMMED_MEAN', 'key', '0', '1']
|
['TDIGEST.TRIMMED_MEAN', 'key', '0', '1']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.tDigest.trimmedMean', async client => {
|
testUtils.testWithClient('client.tDigest.trimmedMean', async client => {
|
||||||
const [, reply] = await Promise.all([
|
const [, reply] = await Promise.all([
|
||||||
client.tDigest.create('key'),
|
client.tDigest.create('key'),
|
||||||
client.tDigest.trimmedMean('key', 0, 1)
|
client.tDigest.trimmedMean('key', 0, 1)
|
||||||
]);
|
]);
|
||||||
|
|
||||||
assert.equal(reply, NaN);
|
assert.equal(reply, NaN);
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -1,20 +1,20 @@
|
|||||||
import { RedisCommandArgument, RedisCommandArguments } from '@redis/client/dist/lib/commands';
|
import { RedisArgument, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
|
import { transformDoubleReply } from '@redis/client/dist/lib/commands/generic-transformers';
|
||||||
|
|
||||||
export const FIRST_KEY_INDEX = 1;
|
export default {
|
||||||
|
FIRST_KEY_INDEX: 1,
|
||||||
export const IS_READ_ONLY = true;
|
IS_READ_ONLY: true,
|
||||||
|
transformArguments(
|
||||||
export function transformArguments(
|
key: RedisArgument,
|
||||||
key: RedisCommandArgument,
|
|
||||||
lowCutPercentile: number,
|
lowCutPercentile: number,
|
||||||
highCutPercentile: number
|
highCutPercentile: number
|
||||||
): RedisCommandArguments {
|
) {
|
||||||
return [
|
return [
|
||||||
'TDIGEST.TRIMMED_MEAN',
|
'TDIGEST.TRIMMED_MEAN',
|
||||||
key,
|
key,
|
||||||
lowCutPercentile.toString(),
|
lowCutPercentile.toString(),
|
||||||
highCutPercentile.toString()
|
highCutPercentile.toString()
|
||||||
];
|
];
|
||||||
}
|
},
|
||||||
|
transformReply: transformDoubleReply
|
||||||
export { transformDoubleReply as transformReply } from '.';
|
} as const satisfies Command;
|
||||||
|
@@ -1,55 +0,0 @@
|
|||||||
import { strict as assert } from 'assert';
|
|
||||||
import { pushCompressionArgument, transformDoubleReply, transformDoublesReply } from '.';
|
|
||||||
|
|
||||||
describe('pushCompressionArgument', () => {
|
|
||||||
it('undefined', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
pushCompressionArgument([]),
|
|
||||||
[]
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('100', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
pushCompressionArgument([], { COMPRESSION: 100 }),
|
|
||||||
['COMPRESSION', '100']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('transformDoubleReply', () => {
|
|
||||||
it('inf', () => {
|
|
||||||
assert.equal(
|
|
||||||
transformDoubleReply('inf'),
|
|
||||||
Infinity
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('-inf', () => {
|
|
||||||
assert.equal(
|
|
||||||
transformDoubleReply('-inf'),
|
|
||||||
-Infinity
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('nan', () => {
|
|
||||||
assert.equal(
|
|
||||||
transformDoubleReply('nan'),
|
|
||||||
NaN
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('0', () => {
|
|
||||||
assert.equal(
|
|
||||||
transformDoubleReply('0'),
|
|
||||||
0
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('transformDoublesReply', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformDoublesReply(['inf', '-inf', 'nan', '0']),
|
|
||||||
[Infinity, -Infinity, NaN, 0]
|
|
||||||
);
|
|
||||||
});
|
|
@@ -1,81 +1,60 @@
|
|||||||
import { RedisCommandArguments } from '@redis/client/dist/lib/commands';
|
import ADD from './ADD';
|
||||||
import * as ADD from './ADD';
|
import BYRANK from './BYRANK';
|
||||||
import * as BYRANK from './BYRANK';
|
import BYREVRANK from './BYREVRANK';
|
||||||
import * as BYREVRANK from './BYREVRANK';
|
import CDF from './CDF';
|
||||||
import * as CDF from './CDF';
|
import CREATE from './CREATE';
|
||||||
import * as CREATE from './CREATE';
|
// import INFO from './INFO';
|
||||||
import * as INFO from './INFO';
|
import MAX from './MAX';
|
||||||
import * as MAX from './MAX';
|
import MERGE from './MERGE';
|
||||||
import * as MERGE from './MERGE';
|
import MIN from './MIN';
|
||||||
import * as MIN from './MIN';
|
import QUANTILE from './QUANTILE';
|
||||||
import * as QUANTILE from './QUANTILE';
|
import RANK from './RANK';
|
||||||
import * as RANK from './RANK';
|
import RESET from './RESET';
|
||||||
import * as RESET from './RESET';
|
import REVRANK from './REVRANK';
|
||||||
import * as REVRANK from './REVRANK';
|
import TRIMMED_MEAN from './TRIMMED_MEAN';
|
||||||
import * as TRIMMED_MEAN from './TRIMMED_MEAN';
|
|
||||||
|
type ADD = typeof import('./ADD').default;
|
||||||
|
type BYRANK = typeof import('./BYRANK').default;
|
||||||
|
type BYREVRANK = typeof import('./BYREVRANK').default;
|
||||||
|
type CDF = typeof import('./CDF').default;
|
||||||
|
type CREATE = typeof import('./CREATE').default;
|
||||||
|
// type INFO = typeof import('./INFO').default;
|
||||||
|
type MAX = typeof import('./MAX').default;
|
||||||
|
type MERGE = typeof import('./MERGE').default;
|
||||||
|
type MIN = typeof import('./MIN').default;
|
||||||
|
type QUANTILE = typeof import('./QUANTILE').default;
|
||||||
|
type RANK = typeof import('./RANK').default;
|
||||||
|
type RESET = typeof import('./RESET').default;
|
||||||
|
type REVRANK = typeof import('./REVRANK').default;
|
||||||
|
type TRIMMED_MEAN = typeof import('./TRIMMED_MEAN').default;
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
ADD,
|
ADD: ADD as ADD,
|
||||||
add: ADD,
|
add: ADD as ADD,
|
||||||
BYRANK,
|
BYRANK: BYRANK as BYRANK,
|
||||||
byRank: BYRANK,
|
byRank: BYRANK as BYRANK,
|
||||||
BYREVRANK,
|
BYREVRANK: BYREVRANK as BYREVRANK,
|
||||||
byRevRank: BYREVRANK,
|
byRevRank: BYREVRANK as BYREVRANK,
|
||||||
CDF,
|
CDF: CDF as CDF,
|
||||||
cdf: CDF,
|
cdf: CDF as CDF,
|
||||||
CREATE,
|
CREATE: CREATE as CREATE,
|
||||||
create: CREATE,
|
create: CREATE as CREATE,
|
||||||
INFO,
|
// INFO: INFO as INFO,
|
||||||
info: INFO,
|
// info: INFO as INFO,
|
||||||
MAX,
|
MAX: MAX as MAX,
|
||||||
max: MAX,
|
max: MAX as MAX,
|
||||||
MERGE,
|
MERGE: MERGE as MERGE,
|
||||||
merge: MERGE,
|
merge: MERGE as MERGE,
|
||||||
MIN,
|
MIN: MIN as MIN,
|
||||||
min: MIN,
|
min: MIN as MIN,
|
||||||
QUANTILE,
|
QUANTILE: QUANTILE as QUANTILE,
|
||||||
quantile: QUANTILE,
|
quantile: QUANTILE as QUANTILE,
|
||||||
RANK,
|
RANK: RANK as RANK,
|
||||||
rank: RANK,
|
rank: RANK as RANK,
|
||||||
RESET,
|
RESET: RESET as RESET,
|
||||||
reset: RESET,
|
reset: RESET as RESET,
|
||||||
REVRANK,
|
REVRANK: REVRANK as REVRANK,
|
||||||
revRank: REVRANK,
|
revRank: REVRANK as REVRANK,
|
||||||
TRIMMED_MEAN,
|
TRIMMED_MEAN: TRIMMED_MEAN as TRIMMED_MEAN,
|
||||||
trimmedMean: TRIMMED_MEAN
|
trimmedMean: TRIMMED_MEAN as TRIMMED_MEAN
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface CompressionOption {
|
|
||||||
COMPRESSION?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function pushCompressionArgument(
|
|
||||||
args: RedisCommandArguments,
|
|
||||||
options?: CompressionOption
|
|
||||||
): RedisCommandArguments {
|
|
||||||
if (options?.COMPRESSION) {
|
|
||||||
args.push('COMPRESSION', options.COMPRESSION.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
return args;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function transformDoubleReply(reply: string): number {
|
|
||||||
switch (reply) {
|
|
||||||
case 'inf':
|
|
||||||
return Infinity;
|
|
||||||
|
|
||||||
case '-inf':
|
|
||||||
return -Infinity;
|
|
||||||
|
|
||||||
case 'nan':
|
|
||||||
return NaN;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return parseFloat(reply);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function transformDoublesReply(reply: Array<string>): Array<number> {
|
|
||||||
return reply.map(transformDoubleReply);
|
|
||||||
}
|
|
||||||
|
@@ -1,22 +1,21 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './ADD';
|
import ADD from './ADD';
|
||||||
|
|
||||||
describe('TOPK ADD', () => {
|
describe('TOPK.ADD', () => {
|
||||||
it('transformArguments', () => {
|
it('transformArguments', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key', 'item'),
|
ADD.transformArguments('key', 'item'),
|
||||||
['TOPK.ADD', 'key', 'item']
|
['TOPK.ADD', 'key', 'item']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.topK.add', async client => {
|
testUtils.testWithClient('client.topK.add', async client => {
|
||||||
await client.topK.reserve('topK', 3);
|
const [, reply] = await Promise.all([
|
||||||
|
client.topK.reserve('topK', 3),
|
||||||
|
client.topK.add('topK', 'item')
|
||||||
|
]);
|
||||||
|
|
||||||
assert.deepEqual(
|
assert.deepEqual(reply, [null]);
|
||||||
await client.topK.add('topK', 'item'),
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
[null]
|
|
||||||
);
|
|
||||||
|
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
|
||||||
});
|
});
|
||||||
|
@@ -1,13 +1,11 @@
|
|||||||
import { RedisCommandArguments } from '@redis/client/dist/lib/commands';
|
import { ArrayReply, SimpleStringReply, Command, RedisArgument } from '@redis/client/dist/lib/RESP/types';
|
||||||
import { pushVariadicArguments } from '@redis/client/dist/lib/commands/generic-transformers';
|
import { RedisVariadicArgument, pushVariadicArguments } from '@redis/client/dist/lib/commands/generic-transformers';
|
||||||
|
|
||||||
export const FIRST_KEY_INDEX = 1;
|
export default {
|
||||||
|
FIRST_KEY_INDEX: 1,
|
||||||
export function transformArguments(
|
IS_READ_ONLY: false,
|
||||||
key: string,
|
transformArguments(key: RedisArgument, items: RedisVariadicArgument) {
|
||||||
items: string | Array<string>
|
|
||||||
): RedisCommandArguments {
|
|
||||||
return pushVariadicArguments(['TOPK.ADD', key], items);
|
return pushVariadicArguments(['TOPK.ADD', key], items);
|
||||||
}
|
},
|
||||||
|
transformReply: undefined as unknown as () => ArrayReply<SimpleStringReply>
|
||||||
export declare function transformReply(): Array<null | string>;
|
} as const satisfies Command;
|
||||||
|
@@ -1,21 +1,21 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './COUNT';
|
import COUNT from './COUNT';
|
||||||
|
|
||||||
describe('TOPK COUNT', () => {
|
describe('TOPK.COUNT', () => {
|
||||||
it('transformArguments', () => {
|
it('transformArguments', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key', 'item'),
|
COUNT.transformArguments('key', 'item'),
|
||||||
['TOPK.COUNT', 'key', 'item']
|
['TOPK.COUNT', 'key', 'item']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.topK.count', async client => {
|
testUtils.testWithClient('client.topK.count', async client => {
|
||||||
await client.topK.reserve('key', 3);
|
const [, reply] = await Promise.all([
|
||||||
|
client.topK.reserve('key', 3),
|
||||||
|
client.topK.count('key', 'item')
|
||||||
|
]);
|
||||||
|
|
||||||
assert.deepEqual(
|
assert.deepEqual(reply, [0]);
|
||||||
await client.topK.count('key', 'item'),
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
[0]
|
|
||||||
);
|
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
|
||||||
});
|
});
|
||||||
|
@@ -1,15 +1,11 @@
|
|||||||
import { RedisCommandArguments } from '@redis/client/dist/lib/commands';
|
import { RedisArgument, ArrayReply, NumberReply, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
import { pushVariadicArguments } from '@redis/client/dist/lib/commands/generic-transformers';
|
import { RedisVariadicArgument, pushVariadicArguments } from '@redis/client/dist/lib/commands/generic-transformers';
|
||||||
|
|
||||||
export const FIRST_KEY_INDEX = 1;
|
export default {
|
||||||
|
FIRST_KEY_INDEX: 1,
|
||||||
export const IS_READ_ONLY = true;
|
IS_READ_ONLY: true,
|
||||||
|
transformArguments(key: RedisArgument, items: RedisVariadicArgument) {
|
||||||
export function transformArguments(
|
|
||||||
key: string,
|
|
||||||
items: string | Array<string>
|
|
||||||
): RedisCommandArguments {
|
|
||||||
return pushVariadicArguments(['TOPK.COUNT', key], items);
|
return pushVariadicArguments(['TOPK.COUNT', key], items);
|
||||||
}
|
},
|
||||||
|
transformReply: undefined as unknown as () => ArrayReply<NumberReply>
|
||||||
export declare function transformReply(): Array<number>;
|
} as const satisfies Command;
|
||||||
|
@@ -1,42 +1,42 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './INCRBY';
|
import INCRBY from './INCRBY';
|
||||||
|
|
||||||
describe('TOPK INCRBY', () => {
|
describe('TOPK.INCRBY', () => {
|
||||||
describe('transformArguments', () => {
|
describe('transformArguments', () => {
|
||||||
it('single item', () => {
|
it('single item', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key', {
|
INCRBY.transformArguments('key', {
|
||||||
item: 'item',
|
item: 'item',
|
||||||
incrementBy: 1
|
incrementBy: 1
|
||||||
}),
|
}),
|
||||||
['TOPK.INCRBY', 'key', 'item', '1']
|
['TOPK.INCRBY', 'key', 'item', '1']
|
||||||
);
|
);
|
||||||
});
|
|
||||||
|
|
||||||
it('multiple items', () => {
|
|
||||||
assert.deepEqual(
|
|
||||||
transformArguments('key', [{
|
|
||||||
item: 'a',
|
|
||||||
incrementBy: 1
|
|
||||||
}, {
|
|
||||||
item: 'b',
|
|
||||||
incrementBy: 2
|
|
||||||
}]),
|
|
||||||
['TOPK.INCRBY', 'key', 'a', '1', 'b', '2']
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.topK.incrby', async client => {
|
it('multiple items', () => {
|
||||||
await client.topK.reserve('key', 5);
|
assert.deepEqual(
|
||||||
|
INCRBY.transformArguments('key', [{
|
||||||
|
item: 'a',
|
||||||
|
incrementBy: 1
|
||||||
|
}, {
|
||||||
|
item: 'b',
|
||||||
|
incrementBy: 2
|
||||||
|
}]),
|
||||||
|
['TOPK.INCRBY', 'key', 'a', '1', 'b', '2']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
assert.deepEqual(
|
testUtils.testWithClient('client.topK.incrby', async client => {
|
||||||
await client.topK.incrBy('key', {
|
const [, reply] = await Promise.all([
|
||||||
item: 'item',
|
client.topK.reserve('key', 5),
|
||||||
incrementBy: 1
|
client.topK.incrBy('key', {
|
||||||
}),
|
item: 'item',
|
||||||
[null]
|
incrementBy: 1
|
||||||
);
|
})
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
]);
|
||||||
|
|
||||||
|
assert.deepEqual(reply, [null]);
|
||||||
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
});
|
});
|
||||||
|
@@ -1,29 +1,32 @@
|
|||||||
export const FIRST_KEY_INDEX = 1;
|
import { RedisArgument, ArrayReply, SimpleStringReply, NullReply, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
|
|
||||||
interface IncrByItem {
|
export interface TopKIncrByItem {
|
||||||
item: string;
|
item: string;
|
||||||
incrementBy: number;
|
incrementBy: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function transformArguments(
|
function pushIncrByItem(args: Array<RedisArgument>, { item, incrementBy }: TopKIncrByItem) {
|
||||||
key: string,
|
args.push(item, incrementBy.toString());
|
||||||
items: IncrByItem | Array<IncrByItem>
|
}
|
||||||
): Array<string> {
|
|
||||||
|
export default {
|
||||||
|
FIRST_KEY_INDEX: 1,
|
||||||
|
IS_READ_ONLY: false,
|
||||||
|
transformArguments(
|
||||||
|
key: RedisArgument,
|
||||||
|
items: TopKIncrByItem | Array<TopKIncrByItem>
|
||||||
|
) {
|
||||||
const args = ['TOPK.INCRBY', key];
|
const args = ['TOPK.INCRBY', key];
|
||||||
|
|
||||||
if (Array.isArray(items)) {
|
if (Array.isArray(items)) {
|
||||||
for (const item of items) {
|
for (const item of items) {
|
||||||
pushIncrByItem(args, item);
|
pushIncrByItem(args, item);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pushIncrByItem(args, items);
|
pushIncrByItem(args, items);
|
||||||
}
|
}
|
||||||
|
|
||||||
return args;
|
return args;
|
||||||
}
|
},
|
||||||
|
transformReply: undefined as unknown as () => ArrayReply<SimpleStringReply | NullReply>
|
||||||
function pushIncrByItem(args: Array<string>, { item, incrementBy }: IncrByItem): void {
|
} as const satisfies Command;
|
||||||
args.push(item, incrementBy.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
export declare function transformReply(): Array<string | null>;
|
|
||||||
|
@@ -1,23 +1,26 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './INFO';
|
import INFO from './INFO';
|
||||||
|
|
||||||
describe('TOPK INFO', () => {
|
describe('TOPK INFO', () => {
|
||||||
it('transformArguments', () => {
|
it('transformArguments', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key'),
|
INFO.transformArguments('key'),
|
||||||
['TOPK.INFO', 'key']
|
['TOPK.INFO', 'key']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.topK.info', async client => {
|
testUtils.testWithClient('client.topK.info', async client => {
|
||||||
await client.topK.reserve('key', 3);
|
const k = 3,
|
||||||
|
[, reply] = await Promise.all([
|
||||||
|
client.topK.reserve('key', 3),
|
||||||
|
client.topK.info('key')
|
||||||
|
]);
|
||||||
|
|
||||||
const info = await client.topK.info('key');
|
assert.equal(typeof reply, 'object');
|
||||||
assert.equal(typeof info, 'object');
|
assert.equal(reply.k, k);
|
||||||
assert.equal(info.k, 3);
|
assert.equal(typeof reply.width, 'number');
|
||||||
assert.equal(typeof info.width, 'number');
|
assert.equal(typeof reply.depth, 'number');
|
||||||
assert.equal(typeof info.depth, 'number');
|
assert.equal(typeof reply.decay, 'number');
|
||||||
assert.equal(typeof info.decay, 'number');
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
|
||||||
});
|
});
|
||||||
|
@@ -1,34 +1,25 @@
|
|||||||
export const FIRST_KEY_INDEX = 1;
|
import { RedisArgument, TuplesToMapReply, BlobStringReply, NumberReply, DoubleReply, Resp2Reply, Command } from '@redis/client/dist/lib/RESP/types';
|
||||||
|
|
||||||
export const IS_READ_ONLY = true;
|
export type TopKInfoReply = TuplesToMapReply<[
|
||||||
|
[BlobStringReply<'k'>, NumberReply],
|
||||||
|
[BlobStringReply<'width'>, NumberReply],
|
||||||
|
[BlobStringReply<'depth'>, NumberReply],
|
||||||
|
[BlobStringReply<'decay'>, DoubleReply]
|
||||||
|
]>;
|
||||||
|
|
||||||
export function transformArguments(key: string): Array<string> {
|
export default {
|
||||||
|
FIRST_KEY_INDEX: 1,
|
||||||
|
IS_READ_ONLY: true,
|
||||||
|
transformArguments(key: RedisArgument) {
|
||||||
return ['TOPK.INFO', key];
|
return ['TOPK.INFO', key];
|
||||||
}
|
},
|
||||||
|
transformReply: {
|
||||||
export type InfoRawReply = [
|
2: (reply: Resp2Reply<TopKInfoReply>) => ({
|
||||||
_: string,
|
k: reply[1],
|
||||||
k: number,
|
width: reply[3],
|
||||||
_: string,
|
depth: reply[5],
|
||||||
width: number,
|
decay: Number(reply[7])
|
||||||
_: string,
|
}),
|
||||||
depth: number,
|
3: undefined as unknown as () => TopKInfoReply
|
||||||
_: string,
|
}
|
||||||
decay: string
|
} as const satisfies Command;
|
||||||
];
|
|
||||||
|
|
||||||
export interface InfoReply {
|
|
||||||
k: number,
|
|
||||||
width: number;
|
|
||||||
depth: number;
|
|
||||||
decay: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function transformReply(reply: InfoRawReply): InfoReply {
|
|
||||||
return {
|
|
||||||
k: reply[1],
|
|
||||||
width: reply[3],
|
|
||||||
depth: reply[5],
|
|
||||||
decay: Number(reply[7])
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
@@ -1,21 +1,21 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import testUtils, { GLOBAL } from '../../test-utils';
|
import testUtils, { GLOBAL } from '../../test-utils';
|
||||||
import { transformArguments } from './LIST';
|
import LIST from './LIST';
|
||||||
|
|
||||||
describe('TOPK LIST', () => {
|
describe('TOPK.LIST', () => {
|
||||||
it('transformArguments', () => {
|
it('transformArguments', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
transformArguments('key'),
|
LIST.transformArguments('key'),
|
||||||
['TOPK.LIST', 'key']
|
['TOPK.LIST', 'key']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.testWithClient('client.topK.list', async client => {
|
testUtils.testWithClient('client.topK.list', async client => {
|
||||||
await client.topK.reserve('key', 3);
|
const [, reply] = await Promise.all([
|
||||||
|
client.topK.reserve('key', 3),
|
||||||
|
client.topK.list('key')
|
||||||
|
]);
|
||||||
|
|
||||||
assert.deepEqual(
|
assert.deepEqual(reply, []);
|
||||||
await client.topK.list('key'),
|
}, GLOBAL.SERVERS.OPEN);
|
||||||
[]
|
|
||||||
);
|
|
||||||
}, GLOBAL.SERVERS.OPEN);
|
|
||||||
});
|
});
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user