npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

browbeat

v0.0.1

Published

Elect a master browser window.

Downloads

5

Readme

Browbeat

Elect a master window using the Bully algorithm.

This is a very early release. Not quite recommended for production.

Why?

Imagine you have a site where it's common for users to open multiple tabs. Maybe you have some realtime functionality or something that requires a lot of AJAX requests or similar. Instead of maintaing one socket or having one message queue (for AJAX) per tab you can have one window being responsible. One sockect connection instead of n socket connections.

How It Works

Browbeat uses localStorage as a message bus for communication between open windows on the same domain. Using the Bully algorithm one window is elected to be the master.

The elected window can then be used to for example keep one open websocket instead of one per tab.

Election Process

  1. A page is loaded. The new page will wait a second to see if a heartbeat from an existing master appears.
  2. If such heartbeat exist the page will happily register itself as a "worker".
  3. If no such heartbeat exists the page will start an election process.
  4. If any other tabs are opened before the election ends they will submit their "vote". A vote is just a number.
  5. Once the election process is over the tab with the highest submitted number becomes the new master.

Local Storage Support

If Browbeat is loaded in a browser that does not support localStorage it will always behave as if it was the master. All the appropriate events etc will be broadcast "locally" on the window once such a condition is detected.

This means you don't have to separate your logic if you want to support all cases.

Using Browbeat

To use Browbeat you simple instantiate a new object using the constructor.

var bb = new Browbeat();

You may optionally pass an options object to the constructor. Available options are:

  • heartbeatTTL, how long to wait for a heartbeat (in ms) before initiating a new election. The actual heartbeat interval will be half of this.
  • electionTime, how long to run the election (in ms) before picking a new master window.
  • gcLimit, upper limit on amount of messages that may be garbage collected everytime the collector runs.
  • debug, when set to true Browbeat will output a tiny amount of debug information to help you determine the current state.

Example

A common usecase would be to manage a single socket connection. You could do this by writing something like this:

var bb = new Browbeat();

// If we win an election, establish a socket connection.
bb.on('wonElection', function won() {
  var socket = new WebSocket('myhost');
  socket.onopen = function connectionOpen() {
    socket.onmessage = function socketMessage(msg) {
      // Forward socket message to slaves
      bb.messageSlaves(msg.data);

      // Use data in this window
      var data = JSON.parse(msg.data);
      alert(data);
    }
  }
});

// Handle messages from master
bb.on('slave', function slaveMessage(msg) {
  var data = JSON.parse(msg.data);
  alert(data);
});

API

Most of the Browbeat API is internal and you should mostly interact with it by listening to events. There are a few methods you need to be aware of though.

resign()

Resign will only work on the current master. It'll trigger the event resigned on the master and stop it's own heartbeat. Which in turn will lead to a new election being initiated.

on(_event_, _handler_)

Register an event listener with Browbeat. The name is the name of the event you want to listen for. handler is the function you want to be triggered when the event is emitted.

The handler will be passed any additional data provided by the event.

off(_event_, _handler_)

Removes the given handler from the given event. hanlder must be a reference to the exact same function as was given to on().

broadcast(_message_)

Sends a message to all open windows on the same domain. Will trigger the broadcast event with the message as the only argument to the handler.

messageMaster(_message_)

Sends a message to the master. Will trigger the master message on the master only, the handler recieves the messages.

messageSlave(_message_)

Sends a message to all slaves. Will trigger the event slave on all open windows that are not the master. The handler recieves the message as it's only argument.

sendMessage(_message_, _data_)

Let's you trigger an arbitrary event on all windows other then the current one. You can use this to dispatch custom events.

Note that data can only be serialized data, ie. you need to stringify JSON first or similar.

Events

Browbeat implements it's own custom event emitter. You can subsrive to events by calling the on() method.

var bb = new Browbeat();
bb.on('wonElection', function () {
  // This window won the election. Establish socket connections etc.
});

Available Events

  • master, emitted when someone sent a message to the master. Will only be triggered on the master window.
  • slave, emitted when someone sent a message to all slaves. Will not be triggered on the master.
  • broadcast, emitted when someone sends a message to everybody.
  • sentMessage, emitted everytime someone sends a message to anybody.
  • wonElection, emitted on the window that one the election.
  • resigned, triggered on the master if it resigns (when the resign() method is called).
  • lostElection, emitted on all the windows that didn't win the election.
  • voting, emitted when the window registers a vote during an election.
  • electionInitiated, emitted when a new election begins.
  • electionConcluded, emitted when an election has concluded.

Custom events can be sent by calling the sendMessage() method. The method takes two arguments; message and data. Message is the event that will be triggered on any other open window.

Browser Support

Should support all major browsers and IE8+.

License

Browbeat is distributed under the MIT license.