index.js
function Leverage(client, sub, options) {
  if (!this) return new Leverage(client, sub, options);

  //
  // Flakey detection if we got a options argument or an actual Redis client. We
  // could do an instanceOf RedisClient check but I don't want to have Redis as
  // a dependency of this module.
  //
  if ('object' === typeof sub && !options && !sub.send_command) {
    options = sub;
    sub = null;
  }

  options = options || {};

  // !IMPORTANT
  //
  // As the scripts are introduced to the `prototype` of our Leverage module we
  // want to make sure that we don't pollute this namespace to much. That's why
  // we've decided to move most of our internal logic in to a `._` private
  // object that contains most of our logic. This way we only have a small
  // number prototypes and properties that should not be overridden by scripts.
  //
  // !IMPORTANT

  this._ = Object.create(null, {
    //
    // The namespace is used to prefix all keys that are used by this module.
    //
    namespace: {
      value: options.namespace || 'leverage'
    },

    //
    // Stores the SHA1 keys from the scripts that are added.
    //
    SHA1: {
      value: options.SHA1 || Object.create(null)
    },

    //
    // Stores the scripts that we're currently using in Leverage
    //
    scripts: {
      value: Leverage.scripts.slice(),
    },

    //
    // The amount of items we should log for our Pub/Sub.
    //
    backlog: {
      value: options.backlog || 100000
    },

    //
    // How many seconds should the item stay alive in our backlog.
    //
    expire: {
      value: options.expire || 1000
    },

    //
    // The pre-configured & authenticated Redis client that is used to send
    // commands and is loaded with the scripts.
    //
    client: {
      value: client
    },

    //
    // Dedicated client that is used for subscribing to a given channel.
    //
    sub: {
      value: sub
    },

    //
    // Introduce a bunch of private methods.
    //
    load:     { value: Leverage.load.bind(this) },
    prepare:  { value: Leverage.prepare.bind(this) },
    refresh:  { value: Leverage.refresh.bind(this) },
    seval:    { value: Leverage.seval.bind(this) }
  });

  //
  // Proxy all readyState changes to another event to make some of our internal
  // usage a bit easier.
  //
  this.on('readystatechange', function readystatechange(state) {
    debug('updated the readyState to %s', state);
    this.emit('readystate#'+ state);
  });

  if (this._.client === this._.sub) {
    throw new Error('The pub and sub clients should separate connections');
  }

  this._.load();
}
function Leverage(client, sub, options) {
  if (!this) return new Leverage(client, sub, options);

  //
  // Flakey detection if we got a options argument or an actual Redis client. We
  // could do an instanceOf RedisClient check but I don't want to have Redis as
  // a dependency of this module.
  //
  if ('object' === typeof sub && !options && !sub.send_command) {
    options = sub;
    sub = null;
  }

  options = options || {};

  // !IMPORTANT
  //
  // As the scripts are introduced to the `prototype` of our Leverage module we
  // want to make sure that we don't pollute this namespace to much. That's why
  // we've decided to move most of our internal logic in to a `._` private
  // object that contains most of our logic. This way we only have a small
  // number prototypes and properties that should not be overridden by scripts.
  //
  // !IMPORTANT

  this._ = Object.create(null, {
    //
    // The namespace is used to prefix all keys that are used by this module.
    //
    namespace: {
      value: options.namespace || 'leverage'
    },

    //
    // Stores the SHA1 keys from the scripts that are added.
    //
    SHA1: {
      value: options.SHA1 || Object.create(null)
    },

    //
    // Stores the scripts that we're currently using in Leverage
    //
    scripts: {
      value: Leverage.scripts.slice(),
    },

    //
    // The amount of items we should log for our Pub/Sub.
    //
    backlog: {
      value: options.backlog || 100000
    },

    //
    // How many seconds should the item stay alive in our backlog.
    //
    expire: {
      value: options.expire || 1000
    },

    //
    // The pre-configured & authenticated Redis client that is used to send
    // commands and is loaded with the scripts.
    //
    client: {
      value: client
    },

    //
    // Dedicated client that is used for subscribing to a given channel.
    //
    sub: {
      value: sub
    },

    //
    // Introduce a bunch of private methods.
    //
    load:     { value: Leverage.load.bind(this) },
    prepare:  { value: Leverage.prepare.bind(this) },
    refresh:  { value: Leverage.refresh.bind(this) },
    seval:    { value: Leverage.seval.bind(this) }
  });

  //
  // Proxy all readyState changes to another event to make some of our internal
  // usage a bit easier.
  //
  this.on('readystatechange', function readystatechange(state) {
    debug('updated the readyState to %s', state);
    this.emit('readystate#'+ state);
  });

  if (this._.client === this._.sub) {
    throw new Error('The pub and sub clients should separate connections');
  }

  this._.load();
}
function Leverage ( client , sub , options ) { if ( ! this ) return new Leverage ( client , sub , options ) ; // // Flakey detection if we got a options argument or an actual Redis client. We // could do an instanceOf RedisClient check but I don't want to have Redis as // a dependency of this module. // if ( 'object' === typeof sub && ! options && ! sub . send_command ) { options = sub ; sub = null ; } options = options || { } ; // !IMPORTANT // // As the scripts are introduced to the `prototype` of our Leverage module we // want to make sure that we don't pollute this namespace to much. That's why // we've decided to move most of our internal logic in to a `._` private // object that contains most of our logic. This way we only have a small // number prototypes and properties that should not be overridden by scripts. // // !IMPORTANT this . _ = Object . create ( null , { // // The namespace is used to prefix all keys that are used by this module. // namespace : { value : options . namespace || 'leverage' } , // // Stores the SHA1 keys from the scripts that are added. // SHA1 : { value : options . SHA1 || Object . create ( null ) } , // // Stores the scripts that we're currently using in Leverage // scripts : { value : Leverage . scripts . slice ( ) , } , // // The amount of items we should log for our Pub/Sub. // backlog : { value : options . backlog || 100000 } , // // How many seconds should the item stay alive in our backlog. // expire : { value : options . expire || 1000 } , // // The pre-configured & authenticated Redis client that is used to send // commands and is loaded with the scripts. // client : { value : client } , // // Dedicated client that is used for subscribing to a given channel. // sub : { value : sub } , // // Introduce a bunch of private methods. // load : { value : Leverage . load . bind ( this ) } , prepare : { value : Leverage . prepare . bind ( this ) } , refresh : { value : Leverage . refresh . bind ( this ) } , seval : { value : Leverage . seval . bind ( this ) } } ) ; // // Proxy all readyState changes to another event to make some of our internal // usage a bit easier. // this . on ( 'readystatechange' , function readystatechange ( state ) { debug ( 'updated the readyState to %s' , state ) ; this . emit ( 'readystate#' + state ) ; } ) ; if ( this . _ . client === this . _ . sub ) { throw new Error ( 'The pub and sub clients should separate connections' ) ; } this . _ . load ( ) ; }
Leverage the awesome power of Lua scripting.

@constructor
@param {Redis} client Redis client to publish the messages over.
@param {Redis} sub Redis client to subscribe with.
@param {Object} options Options.
Leverage the awesome power of Lua scripting .