@owlmeans/redis 0.1.18-rc.40 → 0.1.18-rc.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/agent-meta/manifest.json +2 -2
- package/agent-meta/skills/redis/SKILL.md +1 -1
- package/build/service.d.ts +1 -5
- package/build/service.d.ts.map +1 -1
- package/build/service.js +3 -3
- package/build/service.js.map +1 -1
- package/build/types.local.d.ts +19 -0
- package/build/types.local.d.ts.map +1 -0
- package/build/types.local.js +2 -0
- package/build/types.local.js.map +1 -0
- package/build/utils/cluster.d.ts.map +1 -1
- package/build/utils/cluster.js +2 -2
- package/build/utils/cluster.js.map +1 -1
- package/build/utils/config/types.d.ts +14 -0
- package/build/utils/config/types.d.ts.map +1 -0
- package/build/utils/config/types.js +2 -0
- package/build/utils/config/types.js.map +1 -0
- package/build/utils/config.d.ts +3 -8
- package/build/utils/config.d.ts.map +1 -1
- package/build/utils/config.js +54 -46
- package/build/utils/config.js.map +1 -1
- package/build/utils/instance.js +2 -2
- package/build/utils/instance.js.map +1 -1
- package/package.json +12 -12
- package/src/service.ts +5 -7
- package/src/types.local.ts +21 -0
- package/src/utils/cluster.ts +4 -9
- package/src/utils/config/types.ts +11 -0
- package/src/utils/config.ts +55 -44
- package/src/utils/instance.ts +2 -2
- package/tests/context.ts +6 -3
- package/tests/query.spec.ts +4 -2
- package/tests/resource.spec.ts +4 -2
- package/tests/ttl.spec.ts +4 -2
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ Redis service for OwlMeans server contexts — connection management with cluste
|
|
|
12
12
|
## Installation
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
|
-
bun add @owlmeans/redis@^0.1.18-rc.
|
|
15
|
+
bun add @owlmeans/redis@^0.1.18-rc.42
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
## Usage
|
|
@@ -82,7 +82,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
|
|
|
82
82
|
your project's skill store (`.agents/skills/`):
|
|
83
83
|
|
|
84
84
|
```sh
|
|
85
|
-
npx @owlmeans/agent-skills@^0.1.18-rc.
|
|
85
|
+
npx @owlmeans/agent-skills@^0.1.18-rc.49
|
|
86
86
|
```
|
|
87
87
|
|
|
88
88
|
The embedded files are version-matched to this package release. Do not edit them
|
package/agent-meta/manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
3
|
"package": "@owlmeans/redis",
|
|
4
|
-
"version": "0.1.18-rc.
|
|
5
|
-
"generatedAt": "2026-10-
|
|
4
|
+
"version": "0.1.18-rc.42",
|
|
5
|
+
"generatedAt": "2026-10-05T21:03:06.416Z",
|
|
6
6
|
"canonicalRepo": "https://github.com/owlmeans/common",
|
|
7
7
|
"entries": [
|
|
8
8
|
{
|
|
@@ -8,7 +8,7 @@ user-invocable: false
|
|
|
8
8
|
# @owlmeans/redis
|
|
9
9
|
|
|
10
10
|
**Layer:** Infra
|
|
11
|
-
**Install:** `"@owlmeans/redis": "^0.1.18-rc.
|
|
11
|
+
**Install:** `"@owlmeans/redis": "^0.1.18-rc.42"` in `dependencies`
|
|
12
12
|
|
|
13
13
|
The connection half. The `Resource` contract over those connections is `@owlmeans/redis-resource`;
|
|
14
14
|
queues on them are `@owlmeans/redis-queue`.
|
package/build/service.d.ts
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import type { RedisDbService } from '@owlmeans/redis-resource';
|
|
2
|
-
import type {
|
|
3
|
-
type Config = ServerConfig;
|
|
4
|
-
interface Context<C extends Config = Config> extends ServerContext<C> {
|
|
5
|
-
}
|
|
2
|
+
import type { Config, Context } from './types.local.js';
|
|
6
3
|
export declare const makeRedisService: (alias?: string) => RedisDbService;
|
|
7
4
|
export declare const appendRedis: <C extends Config, T extends Context<C> = Context<C>>(context: T, alias?: string) => T;
|
|
8
|
-
export {};
|
|
9
5
|
//# sourceMappingURL=service.d.ts.map
|
package/build/service.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAwB,MAAM,0BAA0B,CAAA;
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAwB,MAAM,0BAA0B,CAAA;AAKpF,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAGvD,eAAO,MAAM,gBAAgB,WAAW,MAAM,KAAmB,cAgEhE,CAAA;AAED,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,WACpE,CAAC,UAAS,MAAM,KACxB,CAMF,CAAA"}
|
package/build/service.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DEFAULT_ALIAS } from './consts.js';
|
|
2
2
|
import { createDbService } from '@owlmeans/resource';
|
|
3
3
|
import { assertContext } from '@owlmeans/context';
|
|
4
|
-
import { createClient,
|
|
4
|
+
import { createClient, redisOptionsUtils } from './utils/index.js';
|
|
5
5
|
export const makeRedisService = (alias = DEFAULT_ALIAS) => {
|
|
6
6
|
const location = `redis:${alias}`;
|
|
7
7
|
const service = createDbService(alias, {
|
|
@@ -20,8 +20,8 @@ export const makeRedisService = (alias = DEFAULT_ALIAS) => {
|
|
|
20
20
|
const prefix = service.name(configAlias);
|
|
21
21
|
const hosts = Array.isArray(config.host) ? config.host : [config.host];
|
|
22
22
|
return hosts.length > 1
|
|
23
|
-
? { cluster:
|
|
24
|
-
: { single:
|
|
23
|
+
? { cluster: redisOptionsUtils.cluster(config), prefix }
|
|
24
|
+
: { single: redisOptionsUtils.single(config, hosts[0]), prefix };
|
|
25
25
|
},
|
|
26
26
|
initialize: async (configAlias) => {
|
|
27
27
|
configAlias = service.ensureConfigAlias(configAlias);
|
package/build/service.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAIlE,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,KAAK,GAAW,aAAa,EAAkB,EAAE;IAChF,MAAM,QAAQ,GAAG,SAAS,KAAK,EAAE,CAAA;IAEjC,MAAM,OAAO,GAAmB,eAAe,CAC7C,KAAK,EAAE;QACP,EAAE,EAAE,KAAK,EAAC,WAAW,EAAC,EAAE;YACtB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;YAEhD,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;YAE5C;;;eAGG;YACH,OAAO,EAAE,MAAM,EAAG,MAA2C,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAA;QAC3F,CAAC;QAED,OAAO,EAAE,WAAW,CAAC,EAAE;YACrB,WAAW,GAAG,OAAO,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAA;YACpD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;YAC1C,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;YAExC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;YAEtE,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC;gBACrB,CAAC,CAAC,EAAE,OAAO,EAAE,iBAAiB,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE;gBACxD,CAAC,CAAC,EAAE,MAAM,EAAE,iBAAiB,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAA;QACpE,CAAC;QAED,UAAU,EAAE,KAAK,EAAC,WAAW,EAAC,EAAE;YAC9B,WAAW,GAAG,OAAO,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAA;YACpD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;YAE1C,IAAI,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,IAAI,EAAE,CAAC;gBACzC,OAAM;YACR,CAAC;YAED,IAAI,MAAM,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAA;YAEvC,yDAAyD;YAEzD,IAAI,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,IAAI,EAAE,CAAC;gBACzC,MAAM,IAAI,WAAW,CAAC,yCAAyC,WAAW,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC,CAAA;YAClG,CAAC;YAED,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;gBACzB,MAAM,CAAC,IAAI,EAAE,CAAA;YACf,CAAC,CAAC,CAAA;YAEF,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,GAAG,MAAM,CAAA;QACvC,CAAC;KACF,EAAE,OAAO,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE;QACvB,MAAM,OAAO,GAAG,aAAa,CAAkB,OAAO,CAAC,GAAc,EAAE,QAAQ,CAAC,CAAA;QAEhF,oCAAoC;QACpC,MAAM,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,OAAO,KAAK,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;YACpG,MAAM,IAAI,CAAA;YACV,MAAM,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;QACtC,CAAC,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;QAErB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAA;IAC5B,CAAC,CAAC,CAAA;IAEF,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,CACzB,OAAU,EAAE,KAAK,GAAW,aAAa,EACtC,EAAE;IACL,MAAM,OAAO,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAA;IAEvC,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,CAAA;IAEhC,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Redis } from 'ioredis';
|
|
2
|
+
import type { ServerContext, ServerConfig } from '@owlmeans/server-context';
|
|
3
|
+
export type Config = ServerConfig;
|
|
4
|
+
export interface Context<C extends Config = Config> extends ServerContext<C> {
|
|
5
|
+
}
|
|
6
|
+
/** One line of `CLUSTER NODES`, parsed. */
|
|
7
|
+
export interface NodeInfo {
|
|
8
|
+
nodeId: string;
|
|
9
|
+
addr: string;
|
|
10
|
+
flags: string[];
|
|
11
|
+
master: string;
|
|
12
|
+
state: string;
|
|
13
|
+
slots: number[][] | null;
|
|
14
|
+
}
|
|
15
|
+
export interface ClusterNode {
|
|
16
|
+
node: Redis;
|
|
17
|
+
info: NodeInfo;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=types.local.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.local.d.ts","sourceRoot":"","sources":["../src/types.local.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAE3E,MAAM,MAAM,MAAM,GAAG,YAAY,CAAA;AAEjC,MAAM,WAAW,OAAO,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAE,SAAQ,aAAa,CAAC,CAAC,CAAC;CAAI;AAEhF,2CAA2C;AAC3C,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,EAAE,EAAE,GAAG,IAAI,CAAA;CACzB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,KAAK,CAAA;IACX,IAAI,EAAE,QAAQ,CAAA;CACf"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.local.js","sourceRoot":"","sources":["../src/types.local.ts"],"names":[],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cluster.d.ts","sourceRoot":"","sources":["../../src/utils/cluster.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAIjC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"cluster.d.ts","sourceRoot":"","sources":["../../src/utils/cluster.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAIjC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAK5C,eAAO,MAAM,aAAa,WAAkB,QAAQ,CAAC,SAAS,CAAC,KAAG,OAAO,CAAC,OAAO,CAuLhF,CAAA"}
|
package/build/utils/cluster.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { logger } from '@owlmeans/log';
|
|
2
2
|
import { Cluster } from 'ioredis';
|
|
3
|
-
import {
|
|
3
|
+
import { redisOptionsUtils } from './config.js';
|
|
4
4
|
import { createClient } from './instance.js';
|
|
5
5
|
const log = logger('redis:cluster');
|
|
6
6
|
export const ensuerCluster = async (config) => {
|
|
7
7
|
if (!Array.isArray(config.host)) {
|
|
8
8
|
throw new SyntaxError('We may connect to redis cluster only knowing its nodes');
|
|
9
9
|
}
|
|
10
|
-
const setup =
|
|
10
|
+
const setup = redisOptionsUtils.cluster(config);
|
|
11
11
|
// 1. Create single clients for testing
|
|
12
12
|
const clients = await Promise.all(setup.nodes.map(async (node) => {
|
|
13
13
|
if (typeof node !== 'object') {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cluster.js","sourceRoot":"","sources":["../../src/utils/cluster.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAEtC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAEjC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"cluster.js","sourceRoot":"","sources":["../../src/utils/cluster.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { DbConfig } from '@owlmeans/resource';
|
|
2
|
+
import type { RedisOptions, ClusterNode, ClusterOptions } from 'ioredis';
|
|
3
|
+
import type { RedisMeta } from '../../types.js';
|
|
4
|
+
/** ioredis connection options built from a db config. */
|
|
5
|
+
export interface RedisOptionsUtils {
|
|
6
|
+
/** Options for one host: `host` when given, else the config's single host. */
|
|
7
|
+
single: (config: DbConfig<RedisMeta>, host?: string) => RedisOptions;
|
|
8
|
+
/** Options for a cluster over the config's host list. */
|
|
9
|
+
cluster: (config: DbConfig<RedisMeta>) => {
|
|
10
|
+
nodes: ClusterNode[];
|
|
11
|
+
options: ClusterOptions;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/utils/config/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AACxE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAE/C,yDAAyD;AACzD,MAAM,WAAW,iBAAiB;IAChC,8EAA8E;IAC9E,MAAM,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,EAAE,MAAM,KAAK,YAAY,CAAA;IACpE,yDAAyD;IACzD,OAAO,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,SAAS,CAAC,KAAK;QAAE,KAAK,EAAE,WAAW,EAAE,CAAC;QAAC,OAAO,EAAE,cAAc,CAAA;KAAE,CAAA;CAC5F"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/utils/config/types.ts"],"names":[],"mappings":""}
|
package/build/utils/config.d.ts
CHANGED
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export declare const prepareSingleRedisOptions: (config: DbConfig<RedisMeta>, host?: string) => RedisOptions;
|
|
5
|
-
export declare const prepareClusterRedisOptions: (config: DbConfig<RedisMeta>) => {
|
|
6
|
-
nodes: ClusterNode[];
|
|
7
|
-
options: ClusterOptions;
|
|
8
|
-
};
|
|
1
|
+
import type { RedisOptionsUtils } from './config/types.js';
|
|
2
|
+
export declare const createRedisOptionsUtils: () => RedisOptionsUtils;
|
|
3
|
+
export declare const redisOptionsUtils: RedisOptionsUtils;
|
|
9
4
|
//# sourceMappingURL=config.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAE1D,eAAO,MAAM,uBAAuB,QAAO,iBA2D1C,CAAA;AAED,eAAO,MAAM,iBAAiB,mBAA4B,CAAA"}
|
package/build/utils/config.js
CHANGED
|
@@ -1,51 +1,59 @@
|
|
|
1
|
-
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
};
|
|
18
|
-
export const prepareSingleRedisOptions = (config, host) => {
|
|
19
|
-
host = (host != null ? host : config.host);
|
|
20
|
-
if (typeof host !== 'string') {
|
|
21
|
-
throw new SyntaxError('Single redis options can be created only from config referencing single host');
|
|
22
|
-
}
|
|
23
|
-
return {
|
|
24
|
-
host: host,
|
|
25
|
-
port: config.port ?? 6379,
|
|
26
|
-
// Only sent when configured: a bare `requirepass` server rejects AUTH with a username, so an
|
|
27
|
-
// undefined `user` has to stay absent rather than become an empty string.
|
|
28
|
-
...(config.user != null ? { username: config.user } : {}),
|
|
29
|
-
password: config.secret,
|
|
30
|
-
...normalizeRedisMeta(config.meta)
|
|
1
|
+
export const createRedisOptionsUtils = () => {
|
|
2
|
+
// Translate the configurable `dbIndex` (which may arrive as a string from a file-mounted
|
|
3
|
+
// config value) into ioredis' numeric `db` option, and drop `dbIndex` from the spread so
|
|
4
|
+
// it isn't forwarded as an unknown option.
|
|
5
|
+
const normalizeRedisMeta = (meta) => {
|
|
6
|
+
if (meta == null) {
|
|
7
|
+
return {};
|
|
8
|
+
}
|
|
9
|
+
const { dbIndex, ...rest } = meta;
|
|
10
|
+
if (dbIndex == null || `${dbIndex}` === '') {
|
|
11
|
+
return rest;
|
|
12
|
+
}
|
|
13
|
+
const db = Number(dbIndex);
|
|
14
|
+
if (Number.isNaN(db)) {
|
|
15
|
+
throw new SyntaxError(`Invalid redis dbIndex: "${dbIndex}"`);
|
|
16
|
+
}
|
|
17
|
+
return { ...rest, db };
|
|
31
18
|
};
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
19
|
+
const single = (config, host) => {
|
|
20
|
+
host = (host != null ? host : config.host);
|
|
21
|
+
if (typeof host !== 'string') {
|
|
22
|
+
throw new SyntaxError('Single redis options can be created only from config referencing single host');
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
host: host,
|
|
26
|
+
port: config.port ?? 6379,
|
|
27
|
+
// ioredis 6 speaks RESP3 by default, which changes the shape of replies (a hash comes back as a Map);
|
|
28
|
+
// every reader here is written against RESP2, and `meta.protocol` still moves a deployment to 3.
|
|
29
|
+
protocol: 2,
|
|
30
|
+
// Only sent when configured: a bare `requirepass` server rejects AUTH with a username, so an
|
|
31
|
+
// undefined `user` has to stay absent rather than become an empty string.
|
|
32
|
+
...(config.user != null ? { username: config.user } : {}),
|
|
33
|
+
password: config.secret,
|
|
34
|
+
...normalizeRedisMeta(config.meta)
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
const cluster = (config) => {
|
|
38
|
+
if (!Array.isArray(config.host)) {
|
|
39
|
+
throw new SyntaxError('Cluster redis options can be created only from config referencing multiple hosts');
|
|
48
40
|
}
|
|
41
|
+
return {
|
|
42
|
+
nodes: config.host.map(host => ({ host, port: config.port })), options: {
|
|
43
|
+
dnsLookup: (address, callback) => {
|
|
44
|
+
callback(null, address);
|
|
45
|
+
},
|
|
46
|
+
slotsRefreshTimeout: 20000,
|
|
47
|
+
redisOptions: {
|
|
48
|
+
// tls: { rejectUnauthorized: false }, // @TODO check if it's working
|
|
49
|
+
protocol: 2,
|
|
50
|
+
password: config.secret,
|
|
51
|
+
...normalizeRedisMeta(config.meta)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
};
|
|
49
55
|
};
|
|
56
|
+
return { single, cluster };
|
|
50
57
|
};
|
|
58
|
+
export const redisOptionsUtils = createRedisOptionsUtils();
|
|
51
59
|
//# sourceMappingURL=config.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAKA,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAsB,EAAE;IAC7D,yFAAyF;IACzF,yFAAyF;IACzF,2CAA2C;IAC3C,MAAM,kBAAkB,GAAG,CAAC,IAAgB,EAAgB,EAAE;QAC5D,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;YACjB,OAAO,EAAE,CAAA;QACX,CAAC;QACD,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAA;QACjC,IAAI,OAAO,IAAI,IAAI,IAAI,GAAG,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC;YAC3C,OAAO,IAAI,CAAA;QACb,CAAC;QACD,MAAM,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,CAAA;QAC1B,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,WAAW,CAAC,2BAA2B,OAAO,GAAG,CAAC,CAAA;QAC9D,CAAC;QACD,OAAO,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,CAAA;IACxB,CAAC,CAAA;IAED,MAAM,MAAM,GAAG,CAAC,MAA2B,EAAE,IAAa,EAAgB,EAAE;QAC1E,IAAI,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAW,CAAA;QACpD,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC7B,MAAM,IAAI,WAAW,CAAC,8EAA8E,CAAC,CAAA;QACvG,CAAC;QACD,OAAO;YACL,IAAI,EAAE,IAAI;YACV,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,IAAI;YACzB,sGAAsG;YACtG,iGAAiG;YACjG,QAAQ,EAAE,CAAC;YACX,6FAA6F;YAC7F,0EAA0E;YAC1E,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACzD,QAAQ,EAAE,MAAM,CAAC,MAAM;YACvB,GAAG,kBAAkB,CAAC,MAAM,CAAC,IAAI,CAAC;SACnC,CAAA;IACH,CAAC,CAAA;IAED,MAAM,OAAO,GAAG,CAAC,MAA2B,EAAqD,EAAE;QACjG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,WAAW,CAAC,kFAAkF,CAAC,CAAA;QAC3G,CAAC;QACD,OAAO;YACL,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE;gBACtE,SAAS,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE;oBAC/B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;gBACzB,CAAC;gBACD,mBAAmB,EAAE,KAAK;gBAC1B,YAAY,EAAE;oBACZ,qEAAqE;oBACrE,QAAQ,EAAE,CAAC;oBACX,QAAQ,EAAE,MAAM,CAAC,MAAM;oBACvB,GAAG,kBAAkB,CAAC,MAAM,CAAC,IAAI,CAAC;iBACnC;aACF;SACF,CAAA;IACH,CAAC,CAAA;IAED,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAA;AAC5B,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAG,uBAAuB,EAAE,CAAA"}
|
package/build/utils/instance.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Redis } from 'ioredis';
|
|
2
|
-
import {
|
|
2
|
+
import { redisOptionsUtils } from './config.js';
|
|
3
3
|
import { ensuerCluster } from './cluster.js';
|
|
4
4
|
export const createClient = async (config) => {
|
|
5
5
|
if (Array.isArray(config.host) && config.host.length === 1) {
|
|
6
6
|
config.host = config.host[0];
|
|
7
7
|
}
|
|
8
8
|
if (typeof config.host === 'string') {
|
|
9
|
-
return new Redis(
|
|
9
|
+
return new Redis(redisOptionsUtils.single(config));
|
|
10
10
|
}
|
|
11
11
|
return await ensuerCluster(config);
|
|
12
12
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instance.js","sourceRoot":"","sources":["../../src/utils/instance.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,KAAK,EAAC,MAAM,SAAS,CAAA;AAC7B,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"instance.js","sourceRoot":"","sources":["../../src/utils/instance.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,KAAK,EAAC,MAAM,SAAS,CAAA;AAC7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAE5C,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAAE,MAAgB,EAAwB,EAAE;IAC3E,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3D,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC9B,CAAC;IACD,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACpC,OAAO,IAAI,KAAK,CAAC,iBAAiB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAA;IACpD,CAAC;IAED,OAAO,MAAM,aAAa,CAAC,MAAM,CAAC,CAAA;AACpC,CAAC,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owlmeans/redis",
|
|
3
|
-
"version": "0.1.18-rc.
|
|
3
|
+
"version": "0.1.18-rc.42",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -23,21 +23,21 @@
|
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@owlmeans/dep-config": "workspace:*",
|
|
26
|
-
"@owlmeans/test-integration": "^0.1.18-rc.
|
|
27
|
-
"@types/bun": "^1.4.
|
|
28
|
-
"@types/node": "^26.
|
|
26
|
+
"@owlmeans/test-integration": "^0.1.18-rc.33",
|
|
27
|
+
"@types/bun": "^1.4.2",
|
|
28
|
+
"@types/node": "^26.6.4",
|
|
29
29
|
"nodemon": "^3.1.14",
|
|
30
30
|
"typescript": "^7.0.2"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@noble/hashes": "^
|
|
34
|
-
"@owlmeans/context": "^0.1.18-rc.
|
|
35
|
-
"@owlmeans/log": "^0.1.18-rc.
|
|
36
|
-
"@owlmeans/redis-resource": "^0.1.18-rc.
|
|
37
|
-
"@owlmeans/resource": "^0.1.18-rc.
|
|
38
|
-
"@owlmeans/server-context": "^0.1.18-rc.
|
|
39
|
-
"@scure/base": "^2.
|
|
40
|
-
"ioredis": "^
|
|
33
|
+
"@noble/hashes": "^2.4.0",
|
|
34
|
+
"@owlmeans/context": "^0.1.18-rc.34",
|
|
35
|
+
"@owlmeans/log": "^0.1.18-rc.2",
|
|
36
|
+
"@owlmeans/redis-resource": "^0.1.18-rc.44",
|
|
37
|
+
"@owlmeans/resource": "^0.1.18-rc.40",
|
|
38
|
+
"@owlmeans/server-context": "^0.1.18-rc.43",
|
|
39
|
+
"@scure/base": "^2.4.0",
|
|
40
|
+
"ioredis": "^6.0.0"
|
|
41
41
|
},
|
|
42
42
|
"publishConfig": {
|
|
43
43
|
"access": "public"
|
package/src/service.ts
CHANGED
|
@@ -2,11 +2,9 @@ import type { RedisDbService, RedisClient, RedisDb } from '@owlmeans/redis-resou
|
|
|
2
2
|
import { DEFAULT_ALIAS } from './consts.js'
|
|
3
3
|
import { createDbService } from '@owlmeans/resource'
|
|
4
4
|
import { assertContext } from '@owlmeans/context'
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
5
|
+
import { createClient, redisOptionsUtils } from './utils/index.js'
|
|
6
|
+
import type { Config, Context } from './types.local.js'
|
|
7
7
|
|
|
8
|
-
type Config = ServerConfig
|
|
9
|
-
interface Context<C extends Config = Config> extends ServerContext<C> { }
|
|
10
8
|
|
|
11
9
|
export const makeRedisService = (alias: string = DEFAULT_ALIAS): RedisDbService => {
|
|
12
10
|
const location = `redis:${alias}`
|
|
@@ -22,7 +20,7 @@ export const makeRedisService = (alias: string = DEFAULT_ALIAS): RedisDbService
|
|
|
22
20
|
* @TODO we need to think how we can reuse the initail
|
|
23
21
|
* one instead of duplication for some cases
|
|
24
22
|
*/
|
|
25
|
-
return { client: client.duplicate(), prefix: name }
|
|
23
|
+
return { client: (client as { duplicate: () => RedisClient }).duplicate(), prefix: name }
|
|
26
24
|
},
|
|
27
25
|
|
|
28
26
|
options: configAlias => {
|
|
@@ -33,8 +31,8 @@ export const makeRedisService = (alias: string = DEFAULT_ALIAS): RedisDbService
|
|
|
33
31
|
const hosts = Array.isArray(config.host) ? config.host : [config.host]
|
|
34
32
|
|
|
35
33
|
return hosts.length > 1
|
|
36
|
-
? { cluster:
|
|
37
|
-
: { single:
|
|
34
|
+
? { cluster: redisOptionsUtils.cluster(config), prefix }
|
|
35
|
+
: { single: redisOptionsUtils.single(config, hosts[0]), prefix }
|
|
38
36
|
},
|
|
39
37
|
|
|
40
38
|
initialize: async configAlias => {
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Redis } from 'ioredis'
|
|
2
|
+
import type { ServerContext, ServerConfig } from '@owlmeans/server-context'
|
|
3
|
+
|
|
4
|
+
export type Config = ServerConfig
|
|
5
|
+
|
|
6
|
+
export interface Context<C extends Config = Config> extends ServerContext<C> { }
|
|
7
|
+
|
|
8
|
+
/** One line of `CLUSTER NODES`, parsed. */
|
|
9
|
+
export interface NodeInfo {
|
|
10
|
+
nodeId: string
|
|
11
|
+
addr: string
|
|
12
|
+
flags: string[]
|
|
13
|
+
master: string
|
|
14
|
+
state: string
|
|
15
|
+
slots: number[][] | null
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface ClusterNode {
|
|
19
|
+
node: Redis
|
|
20
|
+
info: NodeInfo
|
|
21
|
+
}
|
package/src/utils/cluster.ts
CHANGED
|
@@ -2,9 +2,10 @@ import { logger } from '@owlmeans/log'
|
|
|
2
2
|
import type { DbConfig } from '@owlmeans/resource'
|
|
3
3
|
import { Cluster } from 'ioredis'
|
|
4
4
|
import type { Redis } from 'ioredis'
|
|
5
|
-
import {
|
|
5
|
+
import { redisOptionsUtils } from './config.js'
|
|
6
6
|
import { createClient } from './instance.js'
|
|
7
7
|
import type { RedisMeta } from '../types.js'
|
|
8
|
+
import type { ClusterNode, NodeInfo } from '../types.local.js'
|
|
8
9
|
|
|
9
10
|
const log = logger('redis:cluster')
|
|
10
11
|
|
|
@@ -12,7 +13,7 @@ export const ensuerCluster = async (config: DbConfig<RedisMeta>): Promise<Cluste
|
|
|
12
13
|
if (!Array.isArray(config.host)) {
|
|
13
14
|
throw new SyntaxError('We may connect to redis cluster only knowing its nodes')
|
|
14
15
|
}
|
|
15
|
-
const setup =
|
|
16
|
+
const setup = redisOptionsUtils.cluster(config)
|
|
16
17
|
// 1. Create single clients for testing
|
|
17
18
|
const clients = await Promise.all(setup.nodes.map(
|
|
18
19
|
async node => {
|
|
@@ -193,7 +194,7 @@ export const ensuerCluster = async (config: DbConfig<RedisMeta>): Promise<Cluste
|
|
|
193
194
|
return new Cluster(setup.nodes, setup.options)
|
|
194
195
|
}
|
|
195
196
|
|
|
196
|
-
const parseClusterNodeInfo = (clusterNodes: string) => {
|
|
197
|
+
const parseClusterNodeInfo = (clusterNodes: string): NodeInfo[] => {
|
|
197
198
|
const nodesInfo = clusterNodes.split('\n').filter(line => line.trim() !== '')
|
|
198
199
|
return nodesInfo.map(line => {
|
|
199
200
|
const [nodeId, addr, flags, master, , , , state, ...slots] = line.split(' ')
|
|
@@ -210,9 +211,3 @@ const parseClusterNodeInfo = (clusterNodes: string) => {
|
|
|
210
211
|
})
|
|
211
212
|
}
|
|
212
213
|
|
|
213
|
-
type NodeInfo = ReturnType<typeof parseClusterNodeInfo>[0]
|
|
214
|
-
|
|
215
|
-
interface ClusterNode {
|
|
216
|
-
node: Redis
|
|
217
|
-
info: NodeInfo
|
|
218
|
-
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { DbConfig } from '@owlmeans/resource'
|
|
2
|
+
import type { RedisOptions, ClusterNode, ClusterOptions } from 'ioredis'
|
|
3
|
+
import type { RedisMeta } from '../../types.js'
|
|
4
|
+
|
|
5
|
+
/** ioredis connection options built from a db config. */
|
|
6
|
+
export interface RedisOptionsUtils {
|
|
7
|
+
/** Options for one host: `host` when given, else the config's single host. */
|
|
8
|
+
single: (config: DbConfig<RedisMeta>, host?: string) => RedisOptions
|
|
9
|
+
/** Options for a cluster over the config's host list. */
|
|
10
|
+
cluster: (config: DbConfig<RedisMeta>) => { nodes: ClusterNode[], options: ClusterOptions }
|
|
11
|
+
}
|
package/src/utils/config.ts
CHANGED
|
@@ -1,56 +1,67 @@
|
|
|
1
1
|
import type { DbConfig } from '@owlmeans/resource'
|
|
2
2
|
import type { RedisOptions, ClusterNode, ClusterOptions } from 'ioredis'
|
|
3
3
|
import type { RedisMeta } from '../types.js'
|
|
4
|
+
import type { RedisOptionsUtils } from './config/types.js'
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
6
|
+
export const createRedisOptionsUtils = (): RedisOptionsUtils => {
|
|
7
|
+
// Translate the configurable `dbIndex` (which may arrive as a string from a file-mounted
|
|
8
|
+
// config value) into ioredis' numeric `db` option, and drop `dbIndex` from the spread so
|
|
9
|
+
// it isn't forwarded as an unknown option.
|
|
10
|
+
const normalizeRedisMeta = (meta?: RedisMeta): RedisOptions => {
|
|
11
|
+
if (meta == null) {
|
|
12
|
+
return {}
|
|
13
|
+
}
|
|
14
|
+
const { dbIndex, ...rest } = meta
|
|
15
|
+
if (dbIndex == null || `${dbIndex}` === '') {
|
|
16
|
+
return rest
|
|
17
|
+
}
|
|
18
|
+
const db = Number(dbIndex)
|
|
19
|
+
if (Number.isNaN(db)) {
|
|
20
|
+
throw new SyntaxError(`Invalid redis dbIndex: "${dbIndex}"`)
|
|
21
|
+
}
|
|
22
|
+
return { ...rest, db }
|
|
19
23
|
}
|
|
20
|
-
return { ...rest, db }
|
|
21
|
-
}
|
|
22
24
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
25
|
+
const single = (config: DbConfig<RedisMeta>, host?: string): RedisOptions => {
|
|
26
|
+
host = (host != null ? host : config.host) as string
|
|
27
|
+
if (typeof host !== 'string') {
|
|
28
|
+
throw new SyntaxError('Single redis options can be created only from config referencing single host')
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
host: host,
|
|
32
|
+
port: config.port ?? 6379,
|
|
33
|
+
// ioredis 6 speaks RESP3 by default, which changes the shape of replies (a hash comes back as a Map);
|
|
34
|
+
// every reader here is written against RESP2, and `meta.protocol` still moves a deployment to 3.
|
|
35
|
+
protocol: 2,
|
|
36
|
+
// Only sent when configured: a bare `requirepass` server rejects AUTH with a username, so an
|
|
37
|
+
// undefined `user` has to stay absent rather than become an empty string.
|
|
38
|
+
...(config.user != null ? { username: config.user } : {}),
|
|
39
|
+
password: config.secret,
|
|
40
|
+
...normalizeRedisMeta(config.meta)
|
|
41
|
+
}
|
|
36
42
|
}
|
|
37
|
-
}
|
|
38
43
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
44
|
+
const cluster = (config: DbConfig<RedisMeta>): { nodes: ClusterNode[], options: ClusterOptions } => {
|
|
45
|
+
if (!Array.isArray(config.host)) {
|
|
46
|
+
throw new SyntaxError('Cluster redis options can be created only from config referencing multiple hosts')
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
nodes: config.host.map(host => ({ host, port: config.port })), options: {
|
|
50
|
+
dnsLookup: (address, callback) => {
|
|
51
|
+
callback(null, address)
|
|
52
|
+
},
|
|
53
|
+
slotsRefreshTimeout: 20000,
|
|
54
|
+
redisOptions: {
|
|
55
|
+
// tls: { rejectUnauthorized: false }, // @TODO check if it's working
|
|
56
|
+
protocol: 2,
|
|
57
|
+
password: config.secret,
|
|
58
|
+
...normalizeRedisMeta(config.meta)
|
|
59
|
+
}
|
|
53
60
|
}
|
|
54
61
|
}
|
|
55
62
|
}
|
|
63
|
+
|
|
64
|
+
return { single, cluster }
|
|
56
65
|
}
|
|
66
|
+
|
|
67
|
+
export const redisOptionsUtils = createRedisOptionsUtils()
|
package/src/utils/instance.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { DbConfig } from '@owlmeans/resource'
|
|
2
2
|
import type { RedisClient } from '@owlmeans/redis-resource'
|
|
3
3
|
import {Redis} from 'ioredis'
|
|
4
|
-
import {
|
|
4
|
+
import { redisOptionsUtils } from './config.js'
|
|
5
5
|
import { ensuerCluster } from './cluster.js'
|
|
6
6
|
|
|
7
7
|
export const createClient = async (config: DbConfig): Promise<RedisClient> => {
|
|
@@ -9,7 +9,7 @@ export const createClient = async (config: DbConfig): Promise<RedisClient> => {
|
|
|
9
9
|
config.host = config.host[0]
|
|
10
10
|
}
|
|
11
11
|
if (typeof config.host === 'string') {
|
|
12
|
-
return new Redis(
|
|
12
|
+
return new Redis(redisOptionsUtils.single(config))
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
return await ensuerCluster(config)
|
package/tests/context.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { randomNamespace, gateHelper } from '@owlmeans/test-integration'
|
|
2
2
|
import type { IntegrationGate, RedisEnv } from '@owlmeans/test-integration'
|
|
3
3
|
import { config, makeServerContext } from '@owlmeans/server-context'
|
|
4
4
|
import type { ServerConfig, ServerContext } from '@owlmeans/server-context'
|
|
@@ -7,7 +7,7 @@ import { makeRedisResource } from '@owlmeans/redis-resource'
|
|
|
7
7
|
import type { RedisResource } from '@owlmeans/redis-resource'
|
|
8
8
|
import { appendRedis, DEFAULT_ALIAS } from '@owlmeans/redis'
|
|
9
9
|
|
|
10
|
-
export const gate: IntegrationGate<RedisEnv> = redisGate()
|
|
10
|
+
export const gate: IntegrationGate<RedisEnv> = gateHelper.redisGate()
|
|
11
11
|
|
|
12
12
|
export interface TestRecord extends ResourceRecord {
|
|
13
13
|
id: string
|
|
@@ -33,6 +33,9 @@ export interface RedisSuite {
|
|
|
33
33
|
* alias, because a resource's keys are namespaced by `<schema>-<alias>` and the walk sees every
|
|
34
34
|
* key of the alias it belongs to, including the ones an earlier test in the same file left.
|
|
35
35
|
*/
|
|
36
|
+
/** Hook budget for a suite's teardown: a prefix walk over a shared store, through a port-forward. */
|
|
37
|
+
export const TEARDOWN_TIMEOUT = 60_000
|
|
38
|
+
|
|
36
39
|
export const makeSuite = (label: string): RedisSuite => {
|
|
37
40
|
const base = process.env.REDIS_TEST_KEY_PREFIX ?? 'omt'
|
|
38
41
|
const prefix = randomNamespace(`${base}_${label}`)
|
|
@@ -84,7 +87,7 @@ export const makeSuite = (label: string): RedisSuite => {
|
|
|
84
87
|
const keys: string[] = []
|
|
85
88
|
let cursor = '0'
|
|
86
89
|
do {
|
|
87
|
-
const [next, batch] = await client.scan(cursor, 'MATCH', `${prefix}*`, 'COUNT',
|
|
90
|
+
const [next, batch] = await client.scan(cursor, 'MATCH', `${prefix}*`, 'COUNT', 10_000)
|
|
88
91
|
cursor = next
|
|
89
92
|
keys.push(...batch)
|
|
90
93
|
} while (cursor !== '0')
|
package/tests/query.spec.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { afterAll, describe, expect, test } from 'bun:test'
|
|
2
|
-
import { gate, makeSuite } from './context.js'
|
|
2
|
+
import { gate, makeSuite, TEARDOWN_TIMEOUT } from './context.js'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* The criteria surface.
|
|
@@ -17,9 +17,11 @@ describe('@owlmeans/redis — resource queries', () => {
|
|
|
17
17
|
|
|
18
18
|
const suite = makeSuite('query')
|
|
19
19
|
|
|
20
|
+
// The teardown SCANs a shared store for this suite's prefix; under a full-repo run that walk
|
|
21
|
+
// outlasts the default 5 s hook budget.
|
|
20
22
|
afterAll(async () => {
|
|
21
23
|
await suite.teardown()
|
|
22
|
-
})
|
|
24
|
+
}, TEARDOWN_TIMEOUT)
|
|
23
25
|
|
|
24
26
|
/** `rec-0` … `rec-<count-1>`, alternating `even` / `odd`, in a namespace of their own. */
|
|
25
27
|
const seed = async (alias: string, count: number) => {
|
package/tests/resource.spec.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { afterAll, describe, expect, test } from 'bun:test'
|
|
2
|
-
import { gate, makeSuite } from './context.js'
|
|
2
|
+
import { gate, makeSuite, TEARDOWN_TIMEOUT } from './context.js'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* `delete` / `take` coverage.
|
|
@@ -17,9 +17,11 @@ describe('@owlmeans/redis — resource delete', () => {
|
|
|
17
17
|
|
|
18
18
|
const suite = makeSuite('delete')
|
|
19
19
|
|
|
20
|
+
// The teardown SCANs a shared store for this suite's prefix; under a full-repo run that walk
|
|
21
|
+
// outlasts the default 5 s hook budget.
|
|
20
22
|
afterAll(async () => {
|
|
21
23
|
await suite.teardown()
|
|
22
|
-
})
|
|
24
|
+
}, TEARDOWN_TIMEOUT)
|
|
23
25
|
|
|
24
26
|
test('removes the record when called by id', async () => {
|
|
25
27
|
const { resource } = await suite.boot()
|
package/tests/ttl.spec.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { afterAll, describe, expect, test } from 'bun:test'
|
|
2
|
-
import { gate, makeSuite } from './context.js'
|
|
2
|
+
import { gate, makeSuite, TEARDOWN_TIMEOUT } from './context.js'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* TTL regression coverage.
|
|
@@ -19,9 +19,11 @@ describe('@owlmeans/redis — resource ttl', () => {
|
|
|
19
19
|
/** Generous: the assertion is about the order of magnitude, not clock precision. */
|
|
20
20
|
const tolerance = 5_000
|
|
21
21
|
|
|
22
|
+
// The teardown SCANs a shared store for this suite's prefix; under a full-repo run that walk
|
|
23
|
+
// outlasts the default 5 s hook budget.
|
|
22
24
|
afterAll(async () => {
|
|
23
25
|
await suite.teardown()
|
|
24
|
-
})
|
|
26
|
+
}, TEARDOWN_TIMEOUT)
|
|
25
27
|
|
|
26
28
|
test('a number TTL is seconds from now', async () => {
|
|
27
29
|
const { resource } = await suite.boot()
|