Wednesday, May 10, 2017

BitBit - A little compression library

Ever needed to compress a bunch of settings in a JavaScript object down to fit in a couple of bytes worth of data?  No?  Well that's okay I didn't either until recently.  While working with some embedded systems I needed a way to take simple number and boolean settings in an object, where I could store them in a readable format, and pack those down into under 2 bytes to be sent to and stored on a memory limited device.

Now, bit masks are useful if you're only dealing with multiple boolean values, but I needed to support integers as well, so I needed an easy way to say:  "Ok, bit 0 will be setting A, bits 1-6 will be setting B and bits 7-16 will be setting C."  So I created a little library called BitBit.

BitBit works by letting you create a new BitBit object with a schema that defines how a JavaScript object maps to certain bits.  For example, if you had a thermostat object with settings about a thermostat that you wanted to pack down into under 2 bytes, you could set up a new BitBit object like so:

What this is doing is creating a new BitBit object with a valid schema.  A schema must be an object with string keys that map to an array of 1 or 2 numbers.  A single number means it's a boolean and uses a single field.  2 numbers mean that its mapped to a number that uses the bits spanning the numbers given in the array (inclusive).  If you wanted to return a number that was just 0 or 1, you could use an array with 2 numbers that were the same.

Once you have built the schema, you can pack the settings down into an integer for storage.

As you can see above, once you pack the object, it will ignore anything not specified in the schema, which means you lose that data once it's unpacked.  A good way to use the unpacked data is to merge it back over your original object with lodash.merge.  This works well if the device you're sending it to and from can modify it.

In addition, you can use lodash accessor keys to get nested objects, array indices, etc.  There is an example of that on the Github Readme.

Well, that's about it, it's a small library I created since I needed something like that and didn't see anything out there that existed yet that satisfied those requirements.

If you like it feel free to contribute!  That's all for now, hopefully I'll have more time for these little side projects.