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 🙏

© 2025 – Pkg Stats / Ryan Hefner

ebjs

v6.23.6

Published

Extensible Binary JavaScript Serialization

Readme

Extensible Binary JavaScript Serialization

Build Status Coverage Status

ebjs is an extensible and configurable serialization format with support for nearly as many different data types as numbers can be represented in JavaScript. It produces less bytes than JSON and can also serialize circular references.

Overview

Basic pack / unpack

var ebjs = require('ebjs');

ebjs.pack( {foo: 'bar'} ).
  then( buffer => ebjs.unpack(buffer) ).
  then( data => console.log(data) /* { foo: 'bar' } */ );

Unlike most serialization libraries, ebjs works asynchronously, which means you can serialize almost everything, whether it can be accessed synchronously or not: both ebjs.pack(data) and ebjs.unpack(buffer) return a promise.

ebjs.pack(data) resolves to either a Buffer or an Uint8Array with serialized data. An internal buffer of 1kB will be used unless you specify your own one as the second argument of the call, again, either a Buffer or an Uint8Array. Use ebjs.unpack(buffer) to get back the original data.

Adding new types

Each data type is assigned a label, a number which will be packed into the resulting binary stream. This number will thus identify the data type and should be unique in your whole application. You can use any number you like - except for zero.

A non-normative list of common labels can be found inside definitions/labels.js. You may want to take a look at it in order to avoid collisions with other libraries. If you want your own data type in that list feel free to file an issue and we'll discuss the label.

That being said, there are two kinds of definitions. The firsts and easiest ones are constants:

var someSymbol = Symbol();

ebjs.setConstant(1001,someSymbol);

That's it, you can now transmit someSymbol. Isn't it cool? Next we'll take a look at packers and unpackers. Suppose you want to serialize the following class:

var label = require('ebjs/label');

class Person{

  constructor(name,birthdate,gender){
    this.name = name;
    this.birthdate = new Date(birthdate);
    this.isWoman = gender == 'woman';
  }

  get [label](){ return 1005; }
}

Here we have a String, a Date and a Boolean. Let's define it:

var ebjs = require('ebjs');

ebjs.setPacker(Person,function*(buffer,data){
  yield buffer.pack(data.name, String);
  yield buffer.pack(data.birthdate, Date);
  yield buffer.pack(data.isWoman, Boolean);
});

ebjs.setUnpacker(Person,function*(buffer){
  var name = yield buffer.unpack(String),
      birthdate = yield buffer.unpack(Date),
      isWoman = yield buffer.unpack(Boolean);

  return new Person(name,birthdate,isWoman ? 'woman' : 'man');
});

That's it! Now you can transmit Person instances. You can see more examples under the definitions folder.

Connections

ebjs was designed to be able to serialize anything, and that includes media streams, promises and the like. These types of data need a link between one point and the other in order to transparently transmit messages on the fly, and that's where ebjs connections are used.

We'll use a full example to show how connections work. What we've implemented here is an audio chat roulette service: each client establishes a call with a stranger with every page load. First let's set up a WebSocket server:

var http = require('http'),
    getServer = require('ebjs/connection/server/ws'),
    Connection = require('ebjs/connection'),
    server = getServer(http.createServer().listen(8080));

server.walk(function*(){
  var client1,client2,conn;

  while(true){

    client1 = yield this.until('connection');
    client2 = yield this.until('connection');

    client1.open();
    client2.open();

    conn = new Connection();
    client1.send(conn);
    client2.send(conn.end);

  }

});

As you can see, you can send connections over connections. What this server does is establishing a connection between two consecutive clients. Now let's take a look at the clients:

var getClient = require('ebjs/connection/ws'),
    client = getClient('ws://localhost:8888/');

client.open();
client.walk(function*(){
  var peer = yield this.until('message');

  peer.open();

  // Send the stream

  peer.send(
    navigator.mediaDevices.getUserMedia({audio: true})
  );

  // Receive the stream

  (yield peer.until('message')).then(function(stream){
    var audio = new Audio();

    audio.src = URL.createObjectURL(stream);
    audio.play();
  });

});

Did you see what we've done here? Each client sends to the other, using the connection sent from the server, a promise that will be resolved to the audio stream of the microphone. Internally ebjs uses WebRTC and some subconnection magic to link both peers and achieve above shown level of abstraction.