"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const crypto_1 = require("crypto"); const Command_1 = require("./Command"); const standard_as_callback_1 = require("standard-as-callback"); class Script { constructor(lua, numberOfKeys = null, keyPrefix = "", readOnly = false) { this.lua = lua; this.numberOfKeys = numberOfKeys; this.keyPrefix = keyPrefix; this.readOnly = readOnly; this.sha = (0, crypto_1.createHash)("sha1").update(lua).digest("hex"); const sha = this.sha; const socketHasScriptLoaded = new WeakSet(); this.Command = class CustomScriptCommand extends Command_1.default { toWritable(socket) { const origReject = this.reject; this.reject = (err) => { if (err.message.indexOf("NOSCRIPT") !== -1) { socketHasScriptLoaded.delete(socket); } origReject.call(this, err); }; if (!socketHasScriptLoaded.has(socket)) { socketHasScriptLoaded.add(socket); this.name = "eval"; this.args[0] = lua; } else if (this.name === "eval") { this.name = "evalsha"; this.args[0] = sha; } return super.toWritable(socket); } }; } execute(container, args, options, callback) { if (typeof this.numberOfKeys === "number") { args.unshift(this.numberOfKeys); } if (this.keyPrefix) { options.keyPrefix = this.keyPrefix; } if (this.readOnly) { options.readOnly = true; } const evalsha = new this.Command("evalsha", [this.sha, ...args], options); evalsha.promise = evalsha.promise.catch((err) => { if (err.message.indexOf("NOSCRIPT") === -1) { throw err; } // Resend the same custom evalsha command that gets transformed // to an eval in case it's not loaded yet on the connection. const resend = new this.Command("evalsha", [this.sha, ...args], options); const client = container.isPipeline ? container.redis : container; return client.sendCommand(resend); }); (0, standard_as_callback_1.default)(evalsha.promise, callback); return container.sendCommand(evalsha); } } exports.default = Script;