1.1.1 • Published 2 years ago

superbuffer v1.1.1

Weekly downloads
90
License
MIT
Repository
github
Last release
2 years ago

Introduction

Superbuffer makes it easy to serialize and deserialize data from ArrayBuffers matching the interfaces you define. Its Schema-Model API was inspired by typed-array-buffer-schema.

Superbuffer was designed to balance the readability and flexibility JSON while maximizing compression of your data on the wire. It is especially useful in situations where a high volume and frequency of network traffic between clients is necessary (such as multiplayer networked games).

Installation

NPM

npm i superbuffer

Yarn

yarn add superbuffer

Usage API

Superbuffer allows you to define the shape of the data you want to serialize:

import {Schema, Model, uint32, uint64, int16, string} from 'superbuffer';

const commentSchema = new Schema({
  message: string,
  timestamp: uint64,
  votes: int16,
});

const postSchema = new Schema({
  id: uint32,
  title: string,
  tags: [string],
  author: {
    id: uint32,
    name: string,
  },
  comments: [commentSchema],
});

const post = new Model(postSchema);

If you use Typescript, Superbuffer automatically ensures your data has proper typings:

import {Model, float32} from 'superbuffer';
const position = Model.fromSchemaDefinition({
  x: float32,
  y: float32,
});

// Typescript knows that only objects with type
// {x: number, y: number} can be serialized by the `position` model
const buffer = position.toBuffer({x: 32.1, y: 12.3});

// Typescript knows `result` is of type {x: number, y: number}
const result = position.fromBuffer(buffer);

Superbuffer can serialize any non-circular JSON structure:

import {Schema, Model, views, ExtractSchemaObject} from 'superbuffer';

const {int16, int32, uint8, uint32, uint64, float32, boolean, string} = views;

const playerSchema = new Schema({
  id: uint8,
  x: float32,
  y: float32,
  health: uint8,
  alive: boolean,
});

const inputSchema = new Schema({action: int16, movement: int16});

const listSchema = new Schema({value: int32});

const snapshotModel = Model.fromSchemaDefinition({
  time: uint64,
  sequenceNumber: uint32,
  input: inputSchema,
  messages: [string],
  data: {
    list: [listSchema],
    players: [playerSchema],
  },
});

type Snapshot = ExtractSchemaObject<typeof snapshotModel>;

const snapshot: Snapshot = {
  time: BigInt(Date.now()),
  sequenceNumber: 438923,
  input: {
    action: -12,
    movement: -4,
  },
  messages: ['hello', 'hi', 'how are you', 'im good, how are you', 'fine thank you'],
  data: {
    list: [{value: 1}, {value: 2}, {value: 3}, {value: 4}, {value: 5}],
    players: [
      {id: 14, x: 145.32, y: 98.1123, health: 99, alive: true},
      {id: 15, x: 218.46, y: -14.0934, health: 100, alive: true},
      {id: 0, x: 3289.554, y: -1432.0, health: 0, alive: false},
    ],
  },
};

/** Client */
// JSON.stringify(snapshot) = 430 bytes
// model.toBuffer(snapshot) = 139 bytes
// 68% compression!
const buffer = snapshotModel.toBuffer(snapshot); // Object to ArrayBuffer
network.emit(buffer);

/** Server */
network.on('message', (buffer) => {
  const id = Model.getIdFromBuffer(buffer);
  if (id === snapshotModel.schema.id) {
    const result = snapshotModel.fromBuffer(buffer); // ArrayBuffer to object
  }
});

Data Types

Superbuffer's views are mapped to their respective TypedArray countparts:

Superbuffer ViewTypedArray EquivalentValue RangeByte Size
uint8Uint8Array0 to 2551
uint16Uint16Array0 to 655352
uint32Uint32Array0 to 42949672954
uint64Uint64Array0 to 2^64-18
int8Int8Array-128 to 1271
int16Int16Array-32768 to 327672
int32Int32Array-2147483648 to 21474836474
int64Int64Array-2^63 to 2^63-18
float32Float32Array1.2×10^-38 to 3.4×10^384
float64Float64Array5.0×10^-324 to 1.8×10^3088
stringUint8ArrayUTF-8 encodingvariable
booleanUint8Array0 or 11

Caveats

  • Max array length of 65535 (uint16)
  • Max number of schema ids is 255 (uint8)
  • No " character in strings
  • No null/undefined properties: all properties of the schema definition must be present on an object to be serialized (empty arrays are allowed)

License

MIT License