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

dresscode-binary

v0.0.6

Published

Библиотека кодирования данных в бинарный 6-битный формат (символы из алфавита base64, адаптированного для использования в URL). Код оформлен в методологии [DressCode](https://github.com/Kolyaj/DressCodeJS).

Downloads

4

Readme

dresscode-binary

Библиотека кодирования данных в бинарный 6-битный формат (символы из алфавита base64, адаптированного для использования в URL). Код оформлен в методологии DressCode.

Основная цель создания библиотеки – сохранение данных в localStorage, когда это основное хранилище данных. Binary кодирует данные более компактно и обфусцированно, чем JSON. Можно использовать Binary и для передачи данных с сервера, что уменьшит трафик, но добавит необходимость описания схемы данных.

Для подключения выполните npm i dresscode-binary и добавьте в файл .dresscode строку path-to-node_modules/dresscode-binary/lib.

Философия

В прикладном коде создаются кодировщики с какими-то параметрами. Такой кодировщик может закодировать заданный тип значений, а другой кодировщик с такими же параметрами сможет закодированную строку декодировать в то же самое значение.

Например, кодировщик Binary.Int кодирует целые числа.

var int1 = new Binary.Int();
var data = int1.encode(100); // oG
var int2 = new Binary.Int();
console.log(int2.decode(data)); // 100

При этом конструктор Binary.Int может принимать параметром минимальное значение, меньше которого числа точно не будут. Строки, закодированные таким кодировщиком, нужно декодировать кодировщиком с таким же минимальным значением.

var int1 = new Binary.Int(100);
var data = int1.encode(200);  // kD
var int2 = new Binary.Int();  // не подходящий для декодирования кодировщик
console.log(int2.decode(data)); // 50
var int3 = new Binary.Int(100); // подходящий для декодирования кодировщик
console.log(int3.decode(data)); // 200 

Встроенные кодировщики

Binary.Packet

Основной кодировщик в библиотеке. Принимает схему данных и кодирует объекты именно с теми свойствами и типами значений, которые указаны в схеме. Схема это объект, свойствами которого являются экземпляры кодировщиков, которые будут кодировать свойства с тем же именем.

var packet = new Binary.Packet({
    version: new Binary.Int(0),
    size: new Binary.ArrayOf(new Binary.Int(0))
});
var data = packet.encode({version: 5, size: [10, 20]}); // HFCKU
console.log(packet.decode(data));  // {version: 5, size: [10, 20]}

Пакеты могут быть вложенными.

var packet = new Binary.Packet({
    version: new Binary.Int(0),
    size: new Binary.Packet({
        width: new Binary.Int(0),
        height: new Binary.Int(0)
    })
});

Все свойства в схеме данных являются необязательными.

var data1 = packet.encode({version: 5}); // GF
console.log(packet.decode(data1)); // {version: 5}

Т.к. все свойства необязательные, можно обновлять схему данных добавлением новых свойств в конец списка. Тогда новый пакет сможет декодировать данные, закодированные старым пакетом, что обеспечивает изменение схемы с сохранением обратной совместимости.

var packet1 = new Binary.Packet({
    foo: new Binary.Int()
}); 
var data = packet1.encode({foo: 5}); // DK
var packet2 = new Binary.Packet({
    foo: new Binary.Int(),
    bar: new Binary.String()
});
console.log(packet2.decode(data)); // {foo: 5}

Таким образом для сохранения обратной совместимости с уже закодированными данными при обновлении схемы важно придерживаться двух правил:

1. Никогда не удалять свойства из схемы. Просто кодировать данные без этих свойств и ожидать при декодировании эти свойства могут появиться, если, например, у пользователя в localStorage лежат данные годовой давности.
2. Новые свойства добавлять только в конец списка. 

Binary.Int

Кодирует целое число. Если про кодируемые значения доподлинно известно, что они не меньше какого-то числа, то можно задать это число в качестве минимального значения: new Binary.Int(100), это позволит уменьшить объём закодированных данных. Таким образом беззнаковое целое, т.е. положительные числа, кодируется кодировщиком new Binary.Int(0).

Binary.FixedInt

Кодирует целое число в заранее заданное число символов. Т.к. в один символ умещается 6 бит, то максимальное значение, которое можно закодировать с параметром size: 2 ^ (size * 6) - 1. Например, кодировщик new Binary.FixedInt(3) может кодировать числа от 0 до 262143. Полезно для чисел, про которые известно, что они редко близки к нулю, но точно не превышают определённого значения. Если такие числа кодировать с помощью Binary.Int, то результат будет объёмней из-за использования служебных битов.

Binary.FixedFloat

Кодирует дробное число с заданной точностью. По факту кодировщик new Binary.FixedFloat(N) кодирует целые числа, которые больше исходных в 10^N раз, но на входе и выходе дробное число. Вторым аргументом, как и у Binary.Int, можно задать минимально возможное число.

Binary.String

Кодирует произвольную строку. Параметром можно задать длину кодируемых строк, если она фиксированна: new Binary.String(255).

Binary.Date

Кодирует объект Date.

Binary.Enum

Кодирует одно из предзаданных значений. Сохраняет не само значение, а его индекс в предзаданном массиве.

var encoder = new Binary.Enum(['success', 'error']);
encoder.encode('success');  // A
encoder.encode('error');  // B
encoder.encode('somevalue');  // TypeError: Unexpected value of enum

Binary.ObjectId

Кодирует MongoDB ObjectId в 64-ричный код. На треть сжимает объём текстового представления ObjectId.

Binary.HexColor

Кодирует цвет заданный в формате CSS. Может принимать как трёх-значные цвета (#ccc), так и полные шестизначные (#abcdef). На выходе всегда шестизначный цвет.

Binary.ArrayOf

Массив данных, которые кодируются кодировщиком из первого аргумента. Вторым аргументом можно зафиксировать длину массива.

new Binary.ArrayOf(new Binary.Int(0)); // кодирует массив положительных чисел

Binary.Bitmap

Кодирует массив булевых значений в битовую маску. Максимальная длина маски – 52.

new Binary.Bitmap().encode([true, false, true, false]); // a

Binary.BigBitmap

Кодирует битовые маски любой длины. По факту удобная обёртка вокруг new Binary.ArrayOf(new Binary.Bitmap()).

Binary.UnsafeString

Кодирует произвольную строку "как есть". Если необходимо только сжатие и обфускация данных без url-безопасного кодирования, то произвольные строки имеет смысл кодировать с помощью Binary.UnsafeString вместо Binary.String, т.к. последний выдаст в большинстве случаев слишком раздутый код.

Создание собственных кодировщиков

Скорее всего в вашем приложении будут специфические данные, которые выгоднее не сводить к числам и строкам, а сделать для них свои кодировщики. Например, надо кодировать числа от 0 до 63. В силу своей универсальности у new Binary.Int(0) длина кода будет в среднем 1.5 символа на число. Но зная, что числа находятся в диапазоне от 0 до 63, можно уместить их в 1 символ.

Кодировщик должен наследовать Binary.Type и предоставлять два метода: encodeBuffer и decodeBuffer. encodeBuffer принимает кодируемое значение и экземпляр класса Binary.Buffer, куда требуется записать данные. decodeBuffer принимает экземпляр класса Binary.Buffer, из которого требуется прочитать данные, и возвращает раскодированное значение.

Binary.Buffer имеет два метода, необходимых для работы кодировщика. Метод write принимает число от 0 до 63 и записывает его в закодированную строку в виде символа из алфавита. Метод read читает очередной символ из закодированной строки и возвращает соответствующее число от 0 до 63. Если метод read был вызван, когда данные в буфере уже закончились, бросается исключение RangeError.

var Int0to63 = Bricks.inherit(Binary.Type, {
    encodeBuffer: function(value, buffer) {
        buffer.write(value);
    },
    
    decodeBuffer: function(buffer) {
        return buffer.read();
    }
}); 

Скорее всего у вас не будет необходимости вызывать методы Binary.Buffer напрямую, а достаточно будет использовать уже существующие кодировщики. Совсем искусственный пример: нужно сохранять числа, которые всегда кратны 1000, а значит нет необходимости записывать последние три нуля.

var Thousands = Bricks.inherit(Binary.Type, {
    constructor: function() {
        Thousands.superclass.constructor.apply(this, arguments);
        this._int = new Binary.Int(0);            
    },
    
    encodeBuffer: function(value, buffer) {
        this._int.encodeBuffer(value / 1000, buffer);
    },
    
    decodeBuffer: function(buffer) {
        return this._int.decodeBuffer(buffer) * 1000;
    }
});