JSBT is a library for serializing structured JavaScript data. The library is JavaScript oriented and tries to resolve JS needs for better data serialization.
- Super easy to use (serialization works straight away without using any predefined schemas or structure descriptions).
- Supports main JS types: booleans, numbers (as integers or float), bigints, arrays, typed arrays, objects, sets, maps, symbols, dates.
- Allows encode and decode Object Wrappers for primitive values.
- Created for communication between services written at JavaScript / TypeScript. (Node <-> Browser, Node <-> Node, Browser <-> Browser and so on).
- Optimized for performance and compact size.
- Size optimisation for repeated key or values.
- Supports circular data dependencies.
- Supports serialization for linked objects.
- Supports Streams:
- Supports stream data decoding.
- Possible to parse message before all data is received.
- Allows to send several data structures via one stream message.
- It is much powerful than JSON and could replace JSON for communication between microservices.
- Written on TypeScript and supports types.
- Could be implemented by other languages.
- The small library does not have dependencies.
See specification
> npm install @cheprasov/jsbt
import { JSBT } from '@cheprasov/jsbt';
import { JSBT } from '@cheprasov/jsbt';
const user = {
name: 'Alex',
age: 38,
country: 'UK',
birthday: new Date('1984-10-10')
};
// Encode
const encodedUser = JSBT.encode(user);
// Decode
const decodedUser = JSBT.decode(encodedUser);
// Yes, it supports Date serialisation
console.log(decodedUser.birthday instanceof Date); // true
import { JSBT } from '@cheprasov/jsbt';
const users = {
Alex: {
name: 'Alex',
age: 38,
country: 'UK',
children: null
},
Irina: {
name: 'Irina',
age: 40,
country: 'UK',
children: null,
},
Matvey: {
name: 'Matvey',
age: 2,
parents: null,
},
};
users.Alex.children = users.Irina.children = [users.Matvey];
users.Matvey.parents = [users.Alex, users.Irina];
// Encode
const encodedUsers = JSBT.encode(users);
console.log(encodedUsers.length); // 112
// Decode
const decodedUsers = JSBT.decode(encodedUsers);
console.log(decodedUsers)
console.log(decodedUsers.Alex.children === decodedUsers.Irina.children); // true
console.log(decodedUsers.Matvey.parents[0] === decodedUsers.Alex); // true
console.log(decodedUsers.Matvey.parents[1] === decodedUsers.Irina); // true
For getting props for Encoding Class Instances it will be used first found of the following methods:
toJSBT()
toJSON()
valueOf()
Instance will be encoded like a object simple with props.
Also the decoded object would have configurable, not enumerable and not writable prop __jsbtConstructorName
with construcor name of encoded instance.
import { JSBT } from '@cheprasov/jsbt';
export class User {
protected _name: string;
protected _email: string;
constructor(name: string, email: string) {
this._name = name;
this._email = email;
}
toJSBT() { // or toJSON
return {
name: this._name,
email: this._email,
};
}
}
const user = new User('Alex', '[email protected]');
// Encode
const encodedUser = JSBT.encode(user);
// Decode
const decodedUser = JSBT.decode(encodedUser);
console.log(decodedUser);
// { name: 'Alex', email: 'alex@test.com' }
console.log('Construnctor Name: ', decodedUser.__jsbtConstructorName);
// Construnctor Name: User
import { JSBT } from '@cheprasov/jsbt';
const userData = {
name: 'Alex',
age: 38,
country: 'UK'
};
// Encode user data
const jsbt = JSBT.encode(userData);
import { JSBT } from '@cheprasov/jsbt';
const userData = {
name: 'Alex',
age: 38,
country: 'UK'
};
// Encode user data
const jsbt = JSBT.encode(userData);
// Decode user data
const decodedUser = JSBT.decode(jsbt);
import { JSBT } from '@cheprasov/jsbt';
const stream = new ByteStream();
// on loading add portions of message via stream.addMessages()
const loader = new DataLoader(); // Pseudo loader
// Add loaded data portion to stream
loader.onLoadPortionData((data: string) => {
stream.addMessages(data);
});
// Add last data portion to stream and mark as received all data
loader.onCompleteLoading((data: string) => {
stream.completeStream(data);
});
// Decode data via stream
const data = JSBT.decodeStream(stream); // returns Promise and it will be resolved on receiving enough bytes for decoding data structure
Feel free to fork project, fix bugs, write tests and finally request for pull