index.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. "use strict";
  2. var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
  3. if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
  4. if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
  5. return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
  6. };
  7. var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
  8. if (kind === "m") throw new TypeError("Private method is not writable");
  9. if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
  10. if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
  11. return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
  12. };
  13. var _RedisCluster_instances, _RedisCluster_options, _RedisCluster_slots, _RedisCluster_Multi, _RedisCluster_execute;
  14. Object.defineProperty(exports, "__esModule", { value: true });
  15. const commands_1 = require("./commands");
  16. const cluster_slots_1 = require("./cluster-slots");
  17. const commander_1 = require("../commander");
  18. const events_1 = require("events");
  19. const multi_command_1 = require("./multi-command");
  20. const errors_1 = require("../errors");
  21. class RedisCluster extends events_1.EventEmitter {
  22. static extractFirstKey(command, originalArgs, redisArgs) {
  23. if (command.FIRST_KEY_INDEX === undefined) {
  24. return undefined;
  25. }
  26. else if (typeof command.FIRST_KEY_INDEX === 'number') {
  27. return redisArgs[command.FIRST_KEY_INDEX];
  28. }
  29. return command.FIRST_KEY_INDEX(...originalArgs);
  30. }
  31. static create(options) {
  32. return new ((0, commander_1.attachExtensions)({
  33. BaseClass: RedisCluster,
  34. modulesExecutor: RedisCluster.prototype.commandsExecutor,
  35. modules: options?.modules,
  36. functionsExecutor: RedisCluster.prototype.functionsExecutor,
  37. functions: options?.functions,
  38. scriptsExecutor: RedisCluster.prototype.scriptsExecutor,
  39. scripts: options?.scripts
  40. }))(options);
  41. }
  42. get slots() {
  43. return __classPrivateFieldGet(this, _RedisCluster_slots, "f").slots;
  44. }
  45. get shards() {
  46. return __classPrivateFieldGet(this, _RedisCluster_slots, "f").shards;
  47. }
  48. get masters() {
  49. return __classPrivateFieldGet(this, _RedisCluster_slots, "f").masters;
  50. }
  51. get replicas() {
  52. return __classPrivateFieldGet(this, _RedisCluster_slots, "f").replicas;
  53. }
  54. get nodeByAddress() {
  55. return __classPrivateFieldGet(this, _RedisCluster_slots, "f").nodeByAddress;
  56. }
  57. get pubSubNode() {
  58. return __classPrivateFieldGet(this, _RedisCluster_slots, "f").pubSubNode;
  59. }
  60. get isOpen() {
  61. return __classPrivateFieldGet(this, _RedisCluster_slots, "f").isOpen;
  62. }
  63. constructor(options) {
  64. super();
  65. _RedisCluster_instances.add(this);
  66. _RedisCluster_options.set(this, void 0);
  67. _RedisCluster_slots.set(this, void 0);
  68. _RedisCluster_Multi.set(this, void 0);
  69. Object.defineProperty(this, "multi", {
  70. enumerable: true,
  71. configurable: true,
  72. writable: true,
  73. value: this.MULTI
  74. });
  75. Object.defineProperty(this, "subscribe", {
  76. enumerable: true,
  77. configurable: true,
  78. writable: true,
  79. value: this.SUBSCRIBE
  80. });
  81. Object.defineProperty(this, "unsubscribe", {
  82. enumerable: true,
  83. configurable: true,
  84. writable: true,
  85. value: this.UNSUBSCRIBE
  86. });
  87. Object.defineProperty(this, "pSubscribe", {
  88. enumerable: true,
  89. configurable: true,
  90. writable: true,
  91. value: this.PSUBSCRIBE
  92. });
  93. Object.defineProperty(this, "pUnsubscribe", {
  94. enumerable: true,
  95. configurable: true,
  96. writable: true,
  97. value: this.PUNSUBSCRIBE
  98. });
  99. Object.defineProperty(this, "sSubscribe", {
  100. enumerable: true,
  101. configurable: true,
  102. writable: true,
  103. value: this.SSUBSCRIBE
  104. });
  105. Object.defineProperty(this, "sUnsubscribe", {
  106. enumerable: true,
  107. configurable: true,
  108. writable: true,
  109. value: this.SUNSUBSCRIBE
  110. });
  111. __classPrivateFieldSet(this, _RedisCluster_options, options, "f");
  112. __classPrivateFieldSet(this, _RedisCluster_slots, new cluster_slots_1.default(options, this.emit.bind(this)), "f");
  113. __classPrivateFieldSet(this, _RedisCluster_Multi, multi_command_1.default.extend(options), "f");
  114. }
  115. duplicate(overrides) {
  116. return new (Object.getPrototypeOf(this).constructor)({
  117. ...__classPrivateFieldGet(this, _RedisCluster_options, "f"),
  118. ...overrides
  119. });
  120. }
  121. connect() {
  122. return __classPrivateFieldGet(this, _RedisCluster_slots, "f").connect();
  123. }
  124. async commandsExecutor(command, args) {
  125. const { jsArgs, args: redisArgs, options } = (0, commander_1.transformCommandArguments)(command, args);
  126. return (0, commander_1.transformCommandReply)(command, await this.sendCommand(RedisCluster.extractFirstKey(command, jsArgs, redisArgs), command.IS_READ_ONLY, redisArgs, options), redisArgs.preserve);
  127. }
  128. async sendCommand(firstKey, isReadonly, args, options) {
  129. return __classPrivateFieldGet(this, _RedisCluster_instances, "m", _RedisCluster_execute).call(this, firstKey, isReadonly, client => client.sendCommand(args, options));
  130. }
  131. async functionsExecutor(fn, args, name) {
  132. const { args: redisArgs, options } = (0, commander_1.transformCommandArguments)(fn, args);
  133. return (0, commander_1.transformCommandReply)(fn, await this.executeFunction(name, fn, args, redisArgs, options), redisArgs.preserve);
  134. }
  135. async executeFunction(name, fn, originalArgs, redisArgs, options) {
  136. return __classPrivateFieldGet(this, _RedisCluster_instances, "m", _RedisCluster_execute).call(this, RedisCluster.extractFirstKey(fn, originalArgs, redisArgs), fn.IS_READ_ONLY, client => client.executeFunction(name, fn, redisArgs, options));
  137. }
  138. async scriptsExecutor(script, args) {
  139. const { args: redisArgs, options } = (0, commander_1.transformCommandArguments)(script, args);
  140. return (0, commander_1.transformCommandReply)(script, await this.executeScript(script, args, redisArgs, options), redisArgs.preserve);
  141. }
  142. async executeScript(script, originalArgs, redisArgs, options) {
  143. return __classPrivateFieldGet(this, _RedisCluster_instances, "m", _RedisCluster_execute).call(this, RedisCluster.extractFirstKey(script, originalArgs, redisArgs), script.IS_READ_ONLY, client => client.executeScript(script, redisArgs, options));
  144. }
  145. MULTI(routing) {
  146. return new (__classPrivateFieldGet(this, _RedisCluster_Multi, "f"))((commands, firstKey, chainId) => {
  147. return __classPrivateFieldGet(this, _RedisCluster_instances, "m", _RedisCluster_execute).call(this, firstKey, false, client => client.multiExecutor(commands, undefined, chainId));
  148. }, routing);
  149. }
  150. async SUBSCRIBE(channels, listener, bufferMode) {
  151. return (await __classPrivateFieldGet(this, _RedisCluster_slots, "f").getPubSubClient())
  152. .SUBSCRIBE(channels, listener, bufferMode);
  153. }
  154. async UNSUBSCRIBE(channels, listener, bufferMode) {
  155. return __classPrivateFieldGet(this, _RedisCluster_slots, "f").executeUnsubscribeCommand(client => client.UNSUBSCRIBE(channels, listener, bufferMode));
  156. }
  157. async PSUBSCRIBE(patterns, listener, bufferMode) {
  158. return (await __classPrivateFieldGet(this, _RedisCluster_slots, "f").getPubSubClient())
  159. .PSUBSCRIBE(patterns, listener, bufferMode);
  160. }
  161. async PUNSUBSCRIBE(patterns, listener, bufferMode) {
  162. return __classPrivateFieldGet(this, _RedisCluster_slots, "f").executeUnsubscribeCommand(client => client.PUNSUBSCRIBE(patterns, listener, bufferMode));
  163. }
  164. async SSUBSCRIBE(channels, listener, bufferMode) {
  165. const maxCommandRedirections = __classPrivateFieldGet(this, _RedisCluster_options, "f").maxCommandRedirections ?? 16, firstChannel = Array.isArray(channels) ? channels[0] : channels;
  166. let client = await __classPrivateFieldGet(this, _RedisCluster_slots, "f").getShardedPubSubClient(firstChannel);
  167. for (let i = 0;; i++) {
  168. try {
  169. return await client.SSUBSCRIBE(channels, listener, bufferMode);
  170. }
  171. catch (err) {
  172. if (++i > maxCommandRedirections || !(err instanceof errors_1.ErrorReply)) {
  173. throw err;
  174. }
  175. if (err.message.startsWith('MOVED')) {
  176. await __classPrivateFieldGet(this, _RedisCluster_slots, "f").rediscover(client);
  177. client = await __classPrivateFieldGet(this, _RedisCluster_slots, "f").getShardedPubSubClient(firstChannel);
  178. continue;
  179. }
  180. throw err;
  181. }
  182. }
  183. }
  184. SUNSUBSCRIBE(channels, listener, bufferMode) {
  185. return __classPrivateFieldGet(this, _RedisCluster_slots, "f").executeShardedUnsubscribeCommand(Array.isArray(channels) ? channels[0] : channels, client => client.SUNSUBSCRIBE(channels, listener, bufferMode));
  186. }
  187. quit() {
  188. return __classPrivateFieldGet(this, _RedisCluster_slots, "f").quit();
  189. }
  190. disconnect() {
  191. return __classPrivateFieldGet(this, _RedisCluster_slots, "f").disconnect();
  192. }
  193. nodeClient(node) {
  194. return __classPrivateFieldGet(this, _RedisCluster_slots, "f").nodeClient(node);
  195. }
  196. getRandomNode() {
  197. return __classPrivateFieldGet(this, _RedisCluster_slots, "f").getRandomNode();
  198. }
  199. getSlotRandomNode(slot) {
  200. return __classPrivateFieldGet(this, _RedisCluster_slots, "f").getSlotRandomNode(slot);
  201. }
  202. /**
  203. * @deprecated use `.masters` instead
  204. */
  205. getMasters() {
  206. return this.masters;
  207. }
  208. /**
  209. * @deprecated use `.slots[<SLOT>]` instead
  210. */
  211. getSlotMaster(slot) {
  212. return this.slots[slot].master;
  213. }
  214. }
  215. _RedisCluster_options = new WeakMap(), _RedisCluster_slots = new WeakMap(), _RedisCluster_Multi = new WeakMap(), _RedisCluster_instances = new WeakSet(), _RedisCluster_execute = async function _RedisCluster_execute(firstKey, isReadonly, executor) {
  216. const maxCommandRedirections = __classPrivateFieldGet(this, _RedisCluster_options, "f").maxCommandRedirections ?? 16;
  217. let client = await __classPrivateFieldGet(this, _RedisCluster_slots, "f").getClient(firstKey, isReadonly);
  218. for (let i = 0;; i++) {
  219. try {
  220. return await executor(client);
  221. }
  222. catch (err) {
  223. if (++i > maxCommandRedirections || !(err instanceof errors_1.ErrorReply)) {
  224. throw err;
  225. }
  226. if (err.message.startsWith('ASK')) {
  227. const address = err.message.substring(err.message.lastIndexOf(' ') + 1);
  228. let redirectTo = await __classPrivateFieldGet(this, _RedisCluster_slots, "f").getMasterByAddress(address);
  229. if (!redirectTo) {
  230. await __classPrivateFieldGet(this, _RedisCluster_slots, "f").rediscover(client);
  231. redirectTo = await __classPrivateFieldGet(this, _RedisCluster_slots, "f").getMasterByAddress(address);
  232. }
  233. if (!redirectTo) {
  234. throw new Error(`Cannot find node ${address}`);
  235. }
  236. await redirectTo.asking();
  237. client = redirectTo;
  238. continue;
  239. }
  240. else if (err.message.startsWith('MOVED')) {
  241. await __classPrivateFieldGet(this, _RedisCluster_slots, "f").rediscover(client);
  242. client = await __classPrivateFieldGet(this, _RedisCluster_slots, "f").getClient(firstKey, isReadonly);
  243. continue;
  244. }
  245. throw err;
  246. }
  247. }
  248. };
  249. exports.default = RedisCluster;
  250. (0, commander_1.attachCommands)({
  251. BaseClass: RedisCluster,
  252. commands: commands_1.default,
  253. executor: RedisCluster.prototype.commandsExecutor
  254. });