Script.js 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. const crypto_1 = require("crypto");
  4. const Command_1 = require("./Command");
  5. const standard_as_callback_1 = require("standard-as-callback");
  6. class Script {
  7. constructor(lua, numberOfKeys = null, keyPrefix = "", readOnly = false) {
  8. this.lua = lua;
  9. this.numberOfKeys = numberOfKeys;
  10. this.keyPrefix = keyPrefix;
  11. this.readOnly = readOnly;
  12. this.sha = (0, crypto_1.createHash)("sha1").update(lua).digest("hex");
  13. const sha = this.sha;
  14. const socketHasScriptLoaded = new WeakSet();
  15. this.Command = class CustomScriptCommand extends Command_1.default {
  16. toWritable(socket) {
  17. const origReject = this.reject;
  18. this.reject = (err) => {
  19. if (err.message.indexOf("NOSCRIPT") !== -1) {
  20. socketHasScriptLoaded.delete(socket);
  21. }
  22. origReject.call(this, err);
  23. };
  24. if (!socketHasScriptLoaded.has(socket)) {
  25. socketHasScriptLoaded.add(socket);
  26. this.name = "eval";
  27. this.args[0] = lua;
  28. }
  29. else if (this.name === "eval") {
  30. this.name = "evalsha";
  31. this.args[0] = sha;
  32. }
  33. return super.toWritable(socket);
  34. }
  35. };
  36. }
  37. execute(container, args, options, callback) {
  38. if (typeof this.numberOfKeys === "number") {
  39. args.unshift(this.numberOfKeys);
  40. }
  41. if (this.keyPrefix) {
  42. options.keyPrefix = this.keyPrefix;
  43. }
  44. if (this.readOnly) {
  45. options.readOnly = true;
  46. }
  47. const evalsha = new this.Command("evalsha", [this.sha, ...args], options);
  48. evalsha.promise = evalsha.promise.catch((err) => {
  49. if (err.message.indexOf("NOSCRIPT") === -1) {
  50. throw err;
  51. }
  52. // Resend the same custom evalsha command that gets transformed
  53. // to an eval in case it's not loaded yet on the connection.
  54. const resend = new this.Command("evalsha", [this.sha, ...args], options);
  55. const client = container.isPipeline ? container.redis : container;
  56. return client.sendCommand(resend);
  57. });
  58. (0, standard_as_callback_1.default)(evalsha.promise, callback);
  59. return container.sendCommand(evalsha);
  60. }
  61. }
  62. exports.default = Script;