binarius
Advanced tools
Comparing version 0.0.9 to 0.0.10
54
index.js
/** | ||
* @private | ||
* Use Number if BigInt is not available. | ||
@@ -7,2 +8,3 @@ */ | ||
/** | ||
* @private | ||
* The largest safe integer for bitwise operations. | ||
@@ -14,6 +16,10 @@ */ | ||
/** | ||
* @param {number|Array<number>} data | ||
* @param {number|BigInt|Array<number>} data | ||
* @example | ||
* | ||
* const Person = BinariusFactory([{ name: 'age', size: 7}, { name: 'gender', size: 1}]); | ||
* class Person extends Binarius {} | ||
* Person.fields = [ | ||
* { name: 'age', size: 7 }, | ||
* { name: 'gender', size: 1 }, | ||
* ]; | ||
* new Person([20, 1]).value | ||
@@ -30,2 +36,4 @@ * //=> 41 | ||
const value = Array.isArray(data) ? this.constructor.encode(data) : data; | ||
/** @type {number|BigInt} */ | ||
this.value = isBigInt ? BigInt(value) : value; | ||
@@ -37,7 +45,11 @@ } | ||
* | ||
* @param {string} field name of the field | ||
* @param {string|number} field name of the field | ||
* @returns {number} value value of the field | ||
* @example | ||
* | ||
* const Person = BinariusFactory([{ name: 'age', size: 7}, { name: 'gender', size: 1}]); | ||
* class Person extends Binarius {} | ||
* Person.fields = [ | ||
* { name: 'age', size: 7 }, | ||
* { name: 'gender', size: 1 }, | ||
* ]; | ||
* const person = new Person([20, 1]); | ||
@@ -63,3 +75,7 @@ * person.get('age'); | ||
* | ||
* const Person = BinariusFactory([{ name: 'age', size: 7}, { name: 'gender', size: 1}]); | ||
* class Person extends Binarius {} | ||
* Person.fields = [ | ||
* { name: 'age', size: 7 }, | ||
* { name: 'gender', size: 1 }, | ||
* ]; | ||
* const person = new Person([20, 1]); | ||
@@ -81,3 +97,3 @@ * person.get('age'); | ||
* | ||
* @param {...string} fields names of the fields to check | ||
* @param {...string|number} fields names of the fields to check | ||
* @returns {boolean} whether all the specified fields are set in the instance | ||
@@ -119,3 +135,7 @@ * @example | ||
* | ||
* const Person = BinariusFactory([{ name: 'age', size: 7}, { name: 'gender', size: 1}]); | ||
* class Person extends Binarius {} | ||
* Person.fields = [ | ||
* { name: 'age', size: 7 }, | ||
* { name: 'gender', size: 1 }, | ||
* ]; | ||
* const person = new Person([20, 1]); | ||
@@ -136,3 +156,7 @@ * person.toObject(); | ||
* | ||
* const Person = BinariusFactory([{ name: 'age', size: 7}, { name: 'gender', size: 1}]); | ||
* class Person extends Binarius {} | ||
* Person.fields = [ | ||
* { name: 'age', size: 7 }, | ||
* { name: 'gender', size: 1 }, | ||
* ]; | ||
* Person.encode([20, 1]) | ||
@@ -159,3 +183,7 @@ * //=> 41 | ||
* | ||
* const Person = BinariusFactory([{ name: 'age', size: 7}, { name: 'gender', size: 1}]); | ||
* class Person extends Binarius {} | ||
* Person.fields = [ | ||
* { name: 'age', size: 7 }, | ||
* { name: 'gender', size: 1 }, | ||
* ]; | ||
* Person.decode(41); | ||
@@ -184,3 +212,7 @@ * //=> { age: 20, gender: 1 } | ||
* | ||
* const Person = BinariusFactory([{ name: 'age', size: 7}, { name: 'gender', size: 1}]); | ||
* class Person extends Binarius {} | ||
* Person.fields = [ | ||
* { name: 'age', size: 7 }, | ||
* { name: 'gender', size: 1 }, | ||
* ]; | ||
* Person.isValid({age: 100}) | ||
@@ -287,3 +319,3 @@ * //=> true | ||
/** @type {Array<number>|Array<FieldDescription>} */ | ||
Binarius.fields = new Array(31).fill(1).map((e, i) => i).reverse(); | ||
Binarius.fields = Array.from({ length: 31 }, (e, i) => i).reverse(); | ||
@@ -290,0 +322,0 @@ /** @type {number} */ |
{ | ||
"name": "binarius", | ||
"version": "0.0.9", | ||
"version": "0.0.10", | ||
"description": "Store and operate on data in Numbers and BigInts for memory savings, performance, and fun.", | ||
@@ -29,2 +29,3 @@ "main": "index.js", | ||
"jest": "^23.6.0", | ||
"jsdoc-to-markdown": "^4.0.1", | ||
"tiny-binary-format": "0.0.2" | ||
@@ -36,3 +37,4 @@ }, | ||
"coverage:report": "cat ./coverage/lcov.info | codecov", | ||
"benchmark": "node benchmark.js" | ||
"benchmark": "node benchmark.js", | ||
"docs:api": "jsdoc2md > API.md" | ||
}, | ||
@@ -39,0 +41,0 @@ "jest": { |
155
README.md
@@ -6,3 +6,3 @@ # Binarius | ||
Store and operate on data in Numbers and BigInts for memory savings, performance, and fun. | ||
Store and operate on data in JavaScript Numbers and BigInts for memory savings, performance, and fun. | ||
@@ -17,2 +17,155 @@ ## Installation | ||
Import the class: | ||
```javascript | ||
import Binarius from 'binarius'; | ||
// or | ||
const Binarius = require('binarius'); | ||
``` | ||
By default, Binarius operates on 31 bit long bitfield where bits are indexed from least significant to most: | ||
```javascript | ||
const Binarius = require('binarius'); | ||
const bitfield = new Binarius(29); // 29 === 0b11101 | ||
bitfield.get(0); | ||
//=> 1 | ||
bitfield.get(1); | ||
//=> 0 | ||
bitfield.has(2, 3, 4); | ||
//=> true | ||
``` | ||
You can extend Binarius and use your own schema by specifying field names and their respective sizes in bits: | ||
```javascript | ||
class Person extends Binarius {} | ||
Person.fields = [ | ||
{ name: 'age', size: 7 }, | ||
{ name: 'gender', size: 1 }, | ||
]; | ||
const person = new Person([20, 1]); | ||
person.get('age'); | ||
//=> 20 | ||
person.get('gender'); | ||
//=> 1 | ||
person.set('age', 18); | ||
person.get('age'); | ||
//=> 18 | ||
person.value | ||
//=> 41 | ||
person.toObject(); | ||
//=> { age: 20, gender: 1 } | ||
``` | ||
You can forgo specifying sizes if your field size is 1 bit: | ||
```javascript | ||
class Privileges extends Binarius {} | ||
Privileges.fields = ['user', 'moderator', 'administrator']; | ||
const privileges = new Privileges(0); | ||
privileges.set('user').set('moderator'); | ||
privileges.has('user', 'moderator'); | ||
//=> true | ||
privileges.set('moderator', 0).has('moderator'); | ||
//=> false | ||
``` | ||
If the total size of your fields exceeds 31 bits, Binarius will internally use a BigInt to represent the resulting number, | ||
however, you can still use normal numbers to set each field and get their value as a number as well: | ||
```javascript | ||
class LargeField extends Binarius {} | ||
LargeField.fields = [ | ||
{ name: 'width', size: 20 }, | ||
{ name: 'height', size: 20 }, | ||
]; | ||
const largeField = new LargeField([1048576, 1048576]); | ||
largeField.value | ||
//=> 1099512676352n | ||
largeField.set('width', 1000).get('width') | ||
//=> 1000 | ||
``` | ||
If you have to add more fields to your schema later on, you do not have to re-encode your existing values, just add new fields | ||
at the beginning of your new schema: | ||
```javascript | ||
class OldPerson extends Binarius {} | ||
OldPerson.fields = [ | ||
{ name: 'age', size: 7 }, | ||
{ name: 'gender', size: 1 }, | ||
]; | ||
const oldPerson = OldPerson.encode([20, 1]); | ||
//=> oldPerson === 41 | ||
class Person extends Binarius {} | ||
Person.fields = [ | ||
{ name: 'weight', size: 8 }, | ||
{ name: 'age', size: 7 }, | ||
{ name: 'gender', size: 1 }, | ||
]; | ||
const newPerson = new Person(oldPerson); | ||
newPerson.get('age'); | ||
//=> 20 | ||
newPerson.get('weight'); | ||
//=> 0 | ||
newPerson.set('weight', 100).get('weight'); | ||
//=> 100 | ||
``` | ||
If you only want to encode or decode a set of field values without creating an instance, you can do so by use static methods | ||
`Binarius.encode` and `Binarius.decode` respectively: | ||
```javascript | ||
class Person extends Binarius {} | ||
Person.fields = [ | ||
{ name: 'age', size: 7 }, | ||
{ name: 'gender', size: 1 }, | ||
]; | ||
Person.encode([20, 1]); | ||
//=> 41 | ||
Person.decode(41); | ||
//=> { age: 20, gender: 1 } | ||
``` | ||
If you don't know beforehand how many bits you need for your field, you can call `Binarius.getMinSize` with the maximum | ||
possible value of your field to find out: | ||
```javascript | ||
Binarius.getMinSize(100); | ||
//=> 7 | ||
class Person extends Binarius {} | ||
Person.fields = [ | ||
{ name: 'age', size: Binarius.getMinSize(100) }, | ||
{ name: 'gender', size: 1 }, | ||
]; | ||
``` | ||
For performance sake, Binarius doesn't check the size of values being set and setting values that exceed the specified | ||
field size will lead to undefined behavior. If you want to check whether values fit their respective fields, you can use `Binarius.isValid`: | ||
```javascript | ||
class Person extends Binarius {} | ||
Person.fields = [ | ||
{ name: 'age', size: 7 }, | ||
{ name: 'gender', size: 1 }, | ||
]; | ||
Person.isValid({age: 100}); | ||
//=> true | ||
Person.isValid({age: 100, gender: 3}); | ||
//=> false | ||
Person.isValid([100, 1]); | ||
//=> true | ||
Person.isValid([100, 3]); | ||
//=> false | ||
``` | ||
## Documentation | ||
- [API Documentation](https://github.com/zandaqo/binarius/blob/master/API.md) | ||
## Benchmark | ||
@@ -19,0 +172,0 @@ ``` |
33598
7
451
214
12