@levrbet/shared 0.2.85 → 0.2.87

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.
@@ -8,6 +8,7 @@ export declare const allUrls: {
8
8
  relayer: string;
9
9
  referrals: string;
10
10
  liquidationEngine: string;
11
+ leaderboard: string;
11
12
  indexers: {
12
13
  10143: {
13
14
  type: LevrIndexer;
@@ -23,6 +24,7 @@ export declare const allUrls: {
23
24
  relayer: string;
24
25
  referrals: string;
25
26
  liquidationEngine: string;
27
+ leaderboard: string;
26
28
  indexers: {
27
29
  10143: {
28
30
  type: LevrIndexer;
@@ -38,6 +40,7 @@ export declare const allUrls: {
38
40
  relayer: string;
39
41
  referrals: string;
40
42
  liquidationEngine: string;
43
+ leaderboard: string;
41
44
  indexers: {
42
45
  10143: {
43
46
  type: LevrIndexer;
@@ -53,6 +56,7 @@ export declare const allUrls: {
53
56
  relayer: string;
54
57
  referrals: string;
55
58
  liquidationEngine: string;
59
+ leaderboard: string;
56
60
  indexers: {
57
61
  10143: {
58
62
  type: LevrIndexer;
@@ -13,6 +13,7 @@ exports.allUrls = {
13
13
  relayer: "https://relayers.dev.levr.bet",
14
14
  referrals: "https://referrals.dev.levr.bet",
15
15
  liquidationEngine: "https://liquidation-engine.dev.levr.bet",
16
+ leaderboard: "https://leaderboard.dev.levr.bet",
16
17
  indexers: {
17
18
  [types_1.LevrChain.MONAD_TESTNET]: [
18
19
  { type: indexers_types_1.LevrIndexer.ENVIO, url: "https://indexer.dev.hyperindex.xyz/a07fcc5/v1/graphql" },
@@ -28,6 +29,7 @@ exports.allUrls = {
28
29
  relayer: "https://relayers.dev.levr.bet", //http://levr-v1-openzeppeline-1018367603.ap-south-1.elb.amazonaws.com",
29
30
  referrals: "https://referrals.dev.levr.bet",
30
31
  liquidationEngine: "https://liquidation-engine.dev.levr.bet",
32
+ leaderboard: "https://leaderboard.dev.levr.bet",
31
33
  indexers: {
32
34
  [types_1.LevrChain.MONAD_TESTNET]: [
33
35
  { type: indexers_types_1.LevrIndexer.ENVIO, url: "https://indexer.dev.hyperindex.xyz/a07fcc5/v1/graphql" },
@@ -43,6 +45,7 @@ exports.allUrls = {
43
45
  relayer: "https://relayers.staging.levr.bet",
44
46
  referrals: "https://referrals.staging.levr.bet",
45
47
  liquidationEngine: "https://liquidation-engine.dev.levr.bet",
48
+ leaderboard: "https://leaderboard.staging.levr.bet",
46
49
  indexers: {
47
50
  [types_1.LevrChain.MONAD_TESTNET]: [
48
51
  { type: indexers_types_1.LevrIndexer.ENVIO, url: "https://indexer.staging.levr.app" },
@@ -58,6 +61,7 @@ exports.allUrls = {
58
61
  relayer: "https://relayers.levr.app",
59
62
  referrals: "https://referrals.levr.app",
60
63
  liquidationEngine: "https://liquidation-engine.dev.levr.bet",
64
+ leaderboard: "https://leaderboard.levr.bet",
61
65
  indexers: {
62
66
  [types_1.LevrChain.MONAD_TESTNET]: [
63
67
  { type: indexers_types_1.LevrIndexer.ENVIO, url: "https://indexer.levr.app" },
@@ -1 +1 @@
1
- {"version":3,"file":"urls.js","sourceRoot":"","sources":["../../../src/core/config/urls.ts"],"names":[],"mappings":";;;AAAA,oCAA6C;AAC7C,4DAAqD;AAErD,sBAAsB;AAET,QAAA,OAAO,GAAG;IACnB,CAAC,eAAO,CAAC,KAAK,CAAC,EAAE;QACb,IAAI,EAAE,+BAA+B;QACrC,UAAU,EAAE,kCAAkC;QAC9C,eAAe,EAAE,uCAAuC;QACxD,gBAAgB,EAAE,uCAAuC;QACzD,OAAO,EAAE,+BAA+B;QACxC,SAAS,EAAE,gCAAgC;QAC3C,iBAAiB,EAAE,yCAAyC;QAC5D,QAAQ,EAAE;YACN,CAAC,iBAAS,CAAC,aAAa,CAAC,EAAE;gBACvB,EAAE,IAAI,EAAE,4BAAW,CAAC,KAAK,EAAE,GAAG,EAAE,uDAAuD,EAAE;gBACzF,EAAE,IAAI,EAAE,4BAAW,CAAC,QAAQ,EAAE,GAAG,EAAE,gEAAgE,EAAE;aACxG;SACJ;KACJ;IACD,CAAC,eAAO,CAAC,GAAG,CAAC,EAAE;QACX,IAAI,EAAE,+BAA+B;QACrC,UAAU,EAAE,kCAAkC;QAC9C,eAAe,EAAE,uCAAuC;QACxD,gBAAgB,EAAE,uCAAuC;QACzD,OAAO,EAAE,+BAA+B,EAAE,wEAAwE;QAClH,SAAS,EAAE,gCAAgC;QAC3C,iBAAiB,EAAE,yCAAyC;QAC5D,QAAQ,EAAE;YACN,CAAC,iBAAS,CAAC,aAAa,CAAC,EAAE;gBACvB,EAAE,IAAI,EAAE,4BAAW,CAAC,KAAK,EAAE,GAAG,EAAE,uDAAuD,EAAE;gBACzF,EAAE,IAAI,EAAE,4BAAW,CAAC,QAAQ,EAAE,GAAG,EAAE,wDAAwD,EAAE;aAChG;SACJ;KACJ;IACD,CAAC,eAAO,CAAC,OAAO,CAAC,EAAE;QACf,IAAI,EAAE,oCAAoC;QAC1C,UAAU,EAAE,sCAAsC;QAClD,eAAe,EAAE,2CAA2C;QAC5D,gBAAgB,EAAE,2CAA2C;QAC7D,OAAO,EAAE,mCAAmC;QAC5C,SAAS,EAAE,oCAAoC;QAC/C,iBAAiB,EAAE,yCAAyC;QAC5D,QAAQ,EAAE;YACN,CAAC,iBAAS,CAAC,aAAa,CAAC,EAAE;gBACvB,EAAE,IAAI,EAAE,4BAAW,CAAC,KAAK,EAAE,GAAG,EAAE,kCAAkC,EAAE;gBACpE,EAAE,IAAI,EAAE,4BAAW,CAAC,QAAQ,EAAE,GAAG,EAAE,kCAAkC,EAAE;aAC1E;SACJ;KACJ;IACD,CAAC,eAAO,CAAC,IAAI,CAAC,EAAE;QACZ,IAAI,EAAE,2BAA2B;QACjC,UAAU,EAAE,8BAA8B;QAC1C,eAAe,EAAE,mCAAmC;QACpD,gBAAgB,EAAE,mCAAmC;QACrD,OAAO,EAAE,2BAA2B;QACpC,SAAS,EAAE,4BAA4B;QACvC,iBAAiB,EAAE,yCAAyC;QAC5D,QAAQ,EAAE;YACN,CAAC,iBAAS,CAAC,aAAa,CAAC,EAAE;gBACvB,EAAE,IAAI,EAAE,4BAAW,CAAC,KAAK,EAAE,GAAG,EAAE,0BAA0B,EAAE;gBAC5D,EAAE,IAAI,EAAE,4BAAW,CAAC,QAAQ,EAAE,GAAG,EAAE,0BAA0B,EAAE;aAClE;SACJ;KACJ;CACJ,CAAA"}
1
+ {"version":3,"file":"urls.js","sourceRoot":"","sources":["../../../src/core/config/urls.ts"],"names":[],"mappings":";;;AAAA,oCAA6C;AAC7C,4DAAqD;AAErD,sBAAsB;AAET,QAAA,OAAO,GAAG;IACnB,CAAC,eAAO,CAAC,KAAK,CAAC,EAAE;QACb,IAAI,EAAE,+BAA+B;QACrC,UAAU,EAAE,kCAAkC;QAC9C,eAAe,EAAE,uCAAuC;QACxD,gBAAgB,EAAE,uCAAuC;QACzD,OAAO,EAAE,+BAA+B;QACxC,SAAS,EAAE,gCAAgC;QAC3C,iBAAiB,EAAE,yCAAyC;QAC5D,WAAW,EAAE,kCAAkC;QAC/C,QAAQ,EAAE;YACN,CAAC,iBAAS,CAAC,aAAa,CAAC,EAAE;gBACvB,EAAE,IAAI,EAAE,4BAAW,CAAC,KAAK,EAAE,GAAG,EAAE,uDAAuD,EAAE;gBACzF,EAAE,IAAI,EAAE,4BAAW,CAAC,QAAQ,EAAE,GAAG,EAAE,gEAAgE,EAAE;aACxG;SACJ;KACJ;IACD,CAAC,eAAO,CAAC,GAAG,CAAC,EAAE;QACX,IAAI,EAAE,+BAA+B;QACrC,UAAU,EAAE,kCAAkC;QAC9C,eAAe,EAAE,uCAAuC;QACxD,gBAAgB,EAAE,uCAAuC;QACzD,OAAO,EAAE,+BAA+B,EAAE,wEAAwE;QAClH,SAAS,EAAE,gCAAgC;QAC3C,iBAAiB,EAAE,yCAAyC;QAC5D,WAAW,EAAE,kCAAkC;QAC/C,QAAQ,EAAE;YACN,CAAC,iBAAS,CAAC,aAAa,CAAC,EAAE;gBACvB,EAAE,IAAI,EAAE,4BAAW,CAAC,KAAK,EAAE,GAAG,EAAE,uDAAuD,EAAE;gBACzF,EAAE,IAAI,EAAE,4BAAW,CAAC,QAAQ,EAAE,GAAG,EAAE,wDAAwD,EAAE;aAChG;SACJ;KACJ;IACD,CAAC,eAAO,CAAC,OAAO,CAAC,EAAE;QACf,IAAI,EAAE,oCAAoC;QAC1C,UAAU,EAAE,sCAAsC;QAClD,eAAe,EAAE,2CAA2C;QAC5D,gBAAgB,EAAE,2CAA2C;QAC7D,OAAO,EAAE,mCAAmC;QAC5C,SAAS,EAAE,oCAAoC;QAC/C,iBAAiB,EAAE,yCAAyC;QAC5D,WAAW,EAAE,sCAAsC;QACnD,QAAQ,EAAE;YACN,CAAC,iBAAS,CAAC,aAAa,CAAC,EAAE;gBACvB,EAAE,IAAI,EAAE,4BAAW,CAAC,KAAK,EAAE,GAAG,EAAE,kCAAkC,EAAE;gBACpE,EAAE,IAAI,EAAE,4BAAW,CAAC,QAAQ,EAAE,GAAG,EAAE,kCAAkC,EAAE;aAC1E;SACJ;KACJ;IACD,CAAC,eAAO,CAAC,IAAI,CAAC,EAAE;QACZ,IAAI,EAAE,2BAA2B;QACjC,UAAU,EAAE,8BAA8B;QAC1C,eAAe,EAAE,mCAAmC;QACpD,gBAAgB,EAAE,mCAAmC;QACrD,OAAO,EAAE,2BAA2B;QACpC,SAAS,EAAE,4BAA4B;QACvC,iBAAiB,EAAE,yCAAyC;QAC5D,WAAW,EAAE,8BAA8B;QAC3C,QAAQ,EAAE;YACN,CAAC,iBAAS,CAAC,aAAa,CAAC,EAAE;gBACvB,EAAE,IAAI,EAAE,4BAAW,CAAC,KAAK,EAAE,GAAG,EAAE,0BAA0B,EAAE;gBAC5D,EAAE,IAAI,EAAE,4BAAW,CAAC,QAAQ,EAAE,GAAG,EAAE,0BAA0B,EAAE;aAClE;SACJ;KACJ;CACJ,CAAA"}
@@ -1,5 +1,5 @@
1
1
  import "dotenv/config";
2
- import Redis, { type RedisOptions } from "ioredis";
2
+ import { Cluster, type ClusterOptions, type RedisOptions } from "ioredis";
3
3
  export declare enum RedisDb {
4
4
  ORACLE = 0,
5
5
  ORDERBOOK = 1,
@@ -9,49 +9,75 @@ export declare enum RedisDb {
9
9
  LAB = 5
10
10
  }
11
11
  /**
12
- * Manages Redis client connections including a primary client and optional replica clients.
12
+ * Manages Redis Cluster client connections.
13
13
  *
14
- * This manager provides a singleton-like pattern for initializing and accessing Redis clients.
15
- * It supports both primary and replica connections for load balancing read operations.
14
+ * This manager provides a singleton-like pattern for initializing and accessing Redis Cluster clients.
15
+ * It uses Redis Cluster mode for high availability and automatic sharding.
16
16
  *
17
17
  * **Note:** Not all services that use this package require Redis, so initialization is opt-in.
18
18
  * Call `init()` explicitly before using any Redis clients.
19
19
  *
20
+ * **Important:** Redis Cluster does not support database selection (SELECT command).
21
+ * All operations use database 0. Use key prefixes for logical separation instead.
22
+ *
20
23
  * @example
21
24
  * ```typescript
22
- * redisClientManager.init({ db: RedisDb.ORACLE });
23
- *
24
- * // Get primary client for write operations
25
- * const primary = redisClientManager.primaryClient;
26
- * await primary.set('key', 'value');
25
+ * redisClientManager.init({ keyPrefix: 'oracle:' });
27
26
  *
28
- * // Get replica client for read operations (load balanced)
29
- * const replica = redisClientManager.replicaClient;
30
- * const value = await replica.get('key');
27
+ * // Get cluster client for operations
28
+ * const client = redisClientManager.clusterClient;
29
+ * await client.set('key', 'value');
30
+ * const value = await client.get('key');
31
31
  * ```
32
32
  */
33
33
  declare class RedisClientManager {
34
- private _primaryClient;
35
- private replicaClients;
34
+ private _clusterClient;
36
35
  private initialized;
37
- private dbIndex;
38
36
  /**
39
- * Initializes the Redis client manager with primary and optional replica clients.
37
+ * Initializes the Redis Cluster client manager.
40
38
  *
41
39
  * **Note:** Not all services that use this package require Redis, so initialization is opt-in.
42
40
  * Call this method explicitly before using any Redis clients to avoid initialization errors.
43
41
  *
44
- * @param options - Optional Redis configuration options including database index selection
42
+ * **Important:** Redis Cluster does not support database selection. Use keyPrefix for logical separation.
43
+ *
44
+ * @param options - Optional Redis Cluster configuration options
45
45
  * @example
46
46
  * ```typescript
47
- * // Initialize with a specific database
48
- * redisClientManager.init({ db: RedisDb.AUTH });
47
+ * // Initialize with a key prefix for logical separation
48
+ * redisClientManager.init({ keyPrefix: 'auth:' });
49
49
  * ```
50
50
  */
51
- init(options?: RedisOptions): void;
52
- get primaryClient(): Redis;
53
- get replicaClient(): Redis;
54
- duplicateClient: (clientName: string) => Redis;
51
+ init(options?: Omit<ClusterOptions, "redisOptions"> & {
52
+ redisOptions?: RedisOptions;
53
+ }): void;
54
+ /**
55
+ * Gets the Redis Cluster client.
56
+ * @throws Error if the client manager is not initialized
57
+ */
58
+ get clusterClient(): Cluster;
59
+ /**
60
+ * Alias for clusterClient for backward compatibility.
61
+ * In cluster mode, all nodes handle both reads and writes automatically.
62
+ */
63
+ get primaryClient(): Cluster;
64
+ /**
65
+ * Alias for clusterClient for backward compatibility.
66
+ * In cluster mode, reads are automatically distributed to replicas via scaleReads option.
67
+ */
68
+ get replicaClient(): Cluster;
69
+ /**
70
+ * Creates a duplicate cluster client with the same configuration.
71
+ * Useful for pub/sub or blocking operations that need a dedicated connection.
72
+ *
73
+ * @param clientName - A descriptive name for logging purposes
74
+ * @returns A new Cluster client instance
75
+ */
76
+ duplicateClient: (clientName: string) => Cluster;
77
+ /**
78
+ * Gracefully closes all Redis Cluster connections.
79
+ */
80
+ disconnect(): Promise<void>;
55
81
  }
56
82
  export declare const redisClientManager: RedisClientManager;
57
83
  export {};
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.redisClientManager = exports.RedisDb = void 0;
7
7
  require("dotenv/config");
8
- const ioredis_1 = __importDefault(require("ioredis"));
8
+ const ioredis_1 = require("ioredis");
9
9
  const core_1 = require("../../core");
10
10
  const _1 = require(".");
11
11
  const dotenv_1 = require("./dotenv");
@@ -20,56 +20,80 @@ var RedisDb;
20
20
  RedisDb[RedisDb["LAB"] = 5] = "LAB";
21
21
  })(RedisDb || (exports.RedisDb = RedisDb = {}));
22
22
  /**
23
- * Manages Redis client connections including a primary client and optional replica clients.
23
+ * Parses a Redis URL and extracts connection details.
24
+ * Supports URLs in the format: redis://username:password@host:port
25
+ */
26
+ function parseRedisUrl(url) {
27
+ const parsed = new URL(url);
28
+ return {
29
+ host: parsed.hostname,
30
+ port: Number.parseInt(parsed.port, 10) || 6379,
31
+ username: parsed.username || undefined,
32
+ password: parsed.password || undefined,
33
+ };
34
+ }
35
+ /**
36
+ * Manages Redis Cluster client connections.
24
37
  *
25
- * This manager provides a singleton-like pattern for initializing and accessing Redis clients.
26
- * It supports both primary and replica connections for load balancing read operations.
38
+ * This manager provides a singleton-like pattern for initializing and accessing Redis Cluster clients.
39
+ * It uses Redis Cluster mode for high availability and automatic sharding.
27
40
  *
28
41
  * **Note:** Not all services that use this package require Redis, so initialization is opt-in.
29
42
  * Call `init()` explicitly before using any Redis clients.
30
43
  *
44
+ * **Important:** Redis Cluster does not support database selection (SELECT command).
45
+ * All operations use database 0. Use key prefixes for logical separation instead.
46
+ *
31
47
  * @example
32
48
  * ```typescript
33
- * redisClientManager.init({ db: RedisDb.ORACLE });
49
+ * redisClientManager.init({ keyPrefix: 'oracle:' });
34
50
  *
35
- * // Get primary client for write operations
36
- * const primary = redisClientManager.primaryClient;
37
- * await primary.set('key', 'value');
38
- *
39
- * // Get replica client for read operations (load balanced)
40
- * const replica = redisClientManager.replicaClient;
41
- * const value = await replica.get('key');
51
+ * // Get cluster client for operations
52
+ * const client = redisClientManager.clusterClient;
53
+ * await client.set('key', 'value');
54
+ * const value = await client.get('key');
42
55
  * ```
43
56
  */
44
57
  class RedisClientManager {
45
58
  constructor() {
46
- this._primaryClient = null;
47
- this.replicaClients = [];
59
+ this._clusterClient = null;
48
60
  this.initialized = false;
49
- this.dbIndex = 0;
61
+ /**
62
+ * Creates a duplicate cluster client with the same configuration.
63
+ * Useful for pub/sub or blocking operations that need a dedicated connection.
64
+ *
65
+ * @param clientName - A descriptive name for logging purposes
66
+ * @returns A new Cluster client instance
67
+ */
50
68
  this.duplicateClient = (clientName) => {
51
- const client = this.primaryClient.duplicate();
52
- void client.select(this.dbIndex);
69
+ if (!this._clusterClient)
70
+ throw new Error("RedisClientManager is not initialized. Call init() first.");
71
+ const client = this._clusterClient.duplicate();
53
72
  client.on("error", (err) => {
54
- winston_1.default.error(`Redis ${clientName} client error:`, err);
73
+ winston_1.default.error(`Redis Cluster ${clientName} client error:`, err);
55
74
  });
56
75
  client.on("connect", () => {
57
- winston_1.default.info(`Connected to Redis ${clientName} client`);
76
+ winston_1.default.info(`Connected to Redis Cluster ${clientName} client`);
77
+ });
78
+ client.on("ready", () => {
79
+ winston_1.default.info(`Redis Cluster ${clientName} client is ready`);
58
80
  });
59
81
  return client;
60
82
  };
61
83
  }
62
84
  /**
63
- * Initializes the Redis client manager with primary and optional replica clients.
85
+ * Initializes the Redis Cluster client manager.
64
86
  *
65
87
  * **Note:** Not all services that use this package require Redis, so initialization is opt-in.
66
88
  * Call this method explicitly before using any Redis clients to avoid initialization errors.
67
89
  *
68
- * @param options - Optional Redis configuration options including database index selection
90
+ * **Important:** Redis Cluster does not support database selection. Use keyPrefix for logical separation.
91
+ *
92
+ * @param options - Optional Redis Cluster configuration options
69
93
  * @example
70
94
  * ```typescript
71
- * // Initialize with a specific database
72
- * redisClientManager.init({ db: RedisDb.AUTH });
95
+ * // Initialize with a key prefix for logical separation
96
+ * redisClientManager.init({ keyPrefix: 'auth:' });
73
97
  * ```
74
98
  */
75
99
  init(options) {
@@ -79,51 +103,97 @@ class RedisClientManager {
79
103
  }
80
104
  this.initialized = true;
81
105
  const { REDIS_URL, REDIS_REPLICA_ENDPOINTS } = core_1.Config.init(_1.redisSchema);
106
+ // Parse primary node
107
+ const primaryNode = parseRedisUrl(REDIS_URL);
108
+ // Parse replica nodes
109
+ const replicaEndpoints = REDIS_REPLICA_ENDPOINTS.split(",").filter(Boolean);
110
+ const replicaNodes = replicaEndpoints.map((url) => parseRedisUrl(url));
111
+ // Build cluster nodes list
112
+ const clusterNodes = [
113
+ { host: primaryNode.host, port: primaryNode.port },
114
+ ...replicaNodes.map((node) => ({ host: node.host, port: node.port })),
115
+ ];
82
116
  // Enable TLS for non-dev/local environments
83
117
  const shouldUseTls = dotenv_1.LEVR_ENV !== core_1.LevrEnv.DEV && dotenv_1.LEVR_ENV !== core_1.LevrEnv.LOCAL;
84
- const redisOptions = {
118
+ // Use credentials from the primary node URL
119
+ const clusterOptions = {
85
120
  ...options,
86
- ...(shouldUseTls && {
87
- tls: {},
88
- }),
121
+ redisOptions: {
122
+ ...options?.redisOptions,
123
+ username: primaryNode.username,
124
+ password: primaryNode.password,
125
+ ...(shouldUseTls && {
126
+ tls: {},
127
+ }),
128
+ },
129
+ // Enable reading from replicas for load balancing
130
+ scaleReads: "slave",
131
+ // Retry strategy for cluster connection
132
+ clusterRetryStrategy: (times) => {
133
+ if (times > 10) {
134
+ winston_1.default.error("Redis Cluster: Max retry attempts reached");
135
+ return null;
136
+ }
137
+ return Math.min(times * 100, 3000);
138
+ },
139
+ // Enable NAT mapping if needed (useful for cloud environments)
140
+ enableReadyCheck: true,
141
+ // DNS lookup for cluster nodes
142
+ dnsLookup: (address, callback) => callback(null, address),
89
143
  };
90
- if (options?.db)
91
- this.dbIndex = options.db;
92
- this._primaryClient = new ioredis_1.default(REDIS_URL, redisOptions);
93
- if (options?.db)
94
- void this._primaryClient.select(options.db);
95
- this._primaryClient.on("error", (err) => {
96
- winston_1.default.error("Redis primary client error:", err);
144
+ this._clusterClient = new ioredis_1.Cluster(clusterNodes, clusterOptions);
145
+ this._clusterClient.on("error", (err) => {
146
+ winston_1.default.error("Redis Cluster client error:", err);
97
147
  });
98
- this._primaryClient.on("connect", () => {
99
- winston_1.default.info("Connected to Redis primary");
148
+ this._clusterClient.on("connect", () => {
149
+ winston_1.default.info("Connected to Redis Cluster");
100
150
  });
101
- const replicaEndpoints = REDIS_REPLICA_ENDPOINTS.split(",").filter(Boolean); // Comma-separated list of replica endpoints
102
- this.replicaClients = replicaEndpoints.map((url) => {
103
- const client = new ioredis_1.default(url, redisOptions);
104
- if (options?.db)
105
- void client.select(options.db);
106
- client.on("error", (err) => {
107
- winston_1.default.error(`Redis replica client error for ${client.options.host}:${client.options.port}:`, err);
108
- });
109
- client.on("connect", () => {
110
- winston_1.default.info(`Connected to Redis replica at ${client.options.host}:${client.options.port}`);
111
- });
112
- return client;
151
+ this._clusterClient.on("ready", () => {
152
+ winston_1.default.info("Redis Cluster is ready");
153
+ });
154
+ this._clusterClient.on("node error", (err, address) => {
155
+ winston_1.default.error(`Redis Cluster node error at ${address}:`, err);
156
+ });
157
+ this._clusterClient.on("+node", (node) => {
158
+ winston_1.default.info(`Redis Cluster: New node added - ${node.options.host}:${node.options.port}`);
159
+ });
160
+ this._clusterClient.on("-node", (node) => {
161
+ winston_1.default.warn(`Redis Cluster: Node removed - ${node.options.host}:${node.options.port}`);
113
162
  });
114
163
  }
115
- get primaryClient() {
116
- if (!this._primaryClient)
164
+ /**
165
+ * Gets the Redis Cluster client.
166
+ * @throws Error if the client manager is not initialized
167
+ */
168
+ get clusterClient() {
169
+ if (!this._clusterClient)
117
170
  throw new Error("RedisClientManager is not initialized. Call init() first.");
118
- return this._primaryClient;
171
+ return this._clusterClient;
172
+ }
173
+ /**
174
+ * Alias for clusterClient for backward compatibility.
175
+ * In cluster mode, all nodes handle both reads and writes automatically.
176
+ */
177
+ get primaryClient() {
178
+ return this.clusterClient;
119
179
  }
180
+ /**
181
+ * Alias for clusterClient for backward compatibility.
182
+ * In cluster mode, reads are automatically distributed to replicas via scaleReads option.
183
+ */
120
184
  get replicaClient() {
121
- if (!this.replicaClients.length)
122
- return this.primaryClient;
123
- const index = Math.floor(Math.random() * this.replicaClients.length);
124
- const client = this.replicaClients[index];
125
- client.select(this.dbIndex);
126
- return client;
185
+ return this.clusterClient;
186
+ }
187
+ /**
188
+ * Gracefully closes all Redis Cluster connections.
189
+ */
190
+ async disconnect() {
191
+ if (this._clusterClient) {
192
+ await this._clusterClient.quit();
193
+ this._clusterClient = null;
194
+ this.initialized = false;
195
+ winston_1.default.info("Redis Cluster disconnected");
196
+ }
127
197
  }
128
198
  }
129
199
  exports.redisClientManager = new RedisClientManager();
@@ -1 +1 @@
1
- {"version":3,"file":"redis.js","sourceRoot":"","sources":["../../../src/server/config/redis.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"redis.js","sourceRoot":"","sources":["../../../src/server/config/redis.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,7 @@ export declare const urls: {
6
6
  relayer: string;
7
7
  referrals: string;
8
8
  liquidationEngine: string;
9
+ leaderboard: string;
9
10
  indexers: {
10
11
  10143: {
11
12
  type: import("../../core").LevrIndexer;
@@ -20,6 +21,7 @@ export declare const urls: {
20
21
  relayer: string;
21
22
  referrals: string;
22
23
  liquidationEngine: string;
24
+ leaderboard: string;
23
25
  indexers: {
24
26
  10143: {
25
27
  type: import("../../core").LevrIndexer;
@@ -34,6 +36,7 @@ export declare const urls: {
34
36
  relayer: string;
35
37
  referrals: string;
36
38
  liquidationEngine: string;
39
+ leaderboard: string;
37
40
  indexers: {
38
41
  10143: {
39
42
  type: import("../../core").LevrIndexer;
@@ -48,6 +51,7 @@ export declare const urls: {
48
51
  relayer: string;
49
52
  referrals: string;
50
53
  liquidationEngine: string;
54
+ leaderboard: string;
51
55
  indexers: {
52
56
  10143: {
53
57
  type: import("../../core").LevrIndexer;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@levrbet/shared",
3
- "version": "0.2.85",
3
+ "version": "0.2.87",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "exports": {