Skip to content

Latest commit

 

History

History
152 lines (119 loc) · 5.79 KB

README.md

File metadata and controls

152 lines (119 loc) · 5.79 KB

🔌 tinybuf  NPM version Minzipped Downloads Tests License

tinybuf icon showing binary peeking out from behind a square.

⚡Fast, compressed binary serializers in Node.js and HTML5

🔮 Simple, declarative API 🔥 Blazing fast serialization
🗜️ Powerful compression 💾 ^50% smaller than FlatBuffers
🍃 Zero dependencies 🙉 Strong, inferred types
🌐 Node / browser 🛡️ Built-in validation/transforms
🤏 ~4.4kb minzipped ✅ Property mangling (Terser)

💿 Install

npm install tinybuf

Basic Usage

import { defineFormat, Type } from 'tinybuf';

export const GameWorldState = defineFormat({
  frameNo: Type.UInt,
  timeRemaining: Type.Float16,
  players: [
    {
      id: Type.UInt,
      position: {
        x: Type.Float32,
        y: Type.Float32
      },
      joystick: {
        x: Type.Scalar8,
        y: Type.Scalar8
      },
      actions: Type.Bools // [jump, attack]
    }
  ]
});

Encode

Formats can then be encoded:

let bytes: Uint8Array = GameWorldState.encode({
  frameNo: 50,
  timeRemaining: 59.334,
  players: [
    {
      id: 1,
      position: { x: 123.5, y: 456.75 },
      joystick: { x: 0.75, y: -0.662 },
      actions: [ /* jump: */ true,
               /* attack: */ false ]
    }
  ]
});

bytes.byteLength
// 16

Or directly from objects:

let bytes: Uint8Array = GameWorldState.encode( world );

bytes.byteLength
// 16

Decode

To Object

Decode as a strongly-typed object.

let obj = GameWorldData.decode( bytes );
// { frameNo: number; timeRemaining: number; … }

In-place

Extract fields directly into an existing object (this minimizes memory footprint).

let obj: Decoded<typeof GameWorldData> = {} as any;

GameWorldData.decodeInPlace( bytes, obj );

Parser – Decoding registered formats

  • Register formats with .on(format, handler, options?)
  • Trigger format handlers with .processBuffer(bytes)
import { bufferParser } from 'tinybuf';

// register
const parser = bufferParser()
  .on(MyChatMessage, msg => myHud.showChat(msg))
  .on(GameWorldData, data => myWorld.update(data), {
    decodeInPlace: true, // `data` gets recycled
  });

// parse
parser.processBuffer( bytes );

Types

Type JavaScript Type Bytes Notes
Int number 1-4* A signed integer from -Number.MAX_SAFE_INTEGER to Number.MAX_SAFE_INTEGER.
Int8 number 1 A signed integer from -128 to 127.
Int16 number 2 A signed integer from -32,768 to 32,767.
Int32 number 4 A signed integer from -2,147,483,648 to 2,147,483,647.
UInt number 1-4# An unsigned integer from 0 to Number.MAX_SAFE_INTEGER.
UInt8 number 1 An unsigned integerfrom 0 to 255.
UInt16 number 2 An unsigned integer from 0 to 65,535.
UInt32 number 4 An unsigned integer from 0 to 4,294,967,295.
Float64 number 8 A 64-bit double-precision floating-point number.
Float32 number 4 A 32-bit single-precision floating-point number.
Float16 number 2 A 16-bit half-precision floating-point number.
Note: Low precision. Maximum effective range ±65,504.
BFloat16 number 2 A bfloat16 format 16-bit half-precision floating-point number.
Note: Lowest precision. Same effective range as Float32.
Scalar number 1 A signed scalar between -1.00 and 1.00 (two decimal precision).
UScalar number 1 A scalar between 0.00 and 1.00 (two decimal precision).
Bool boolean 1 A boolean value.
Bools boolean[] 1 An array/tuple of boolean values (1 - 28) encoded as a single byte.
Buffer Uint8Array 1 + n An ArrayBuffer or ArrayBufferLike.
String string 1 + n A string (UTF-8 encoded).
JSON any 1 + n Any JSON encodable value (encoded as a string).
RegExp RegExp 2 + n JavaScript RegExp object.
Date Date 8 JavaScript Date object.

📘 Documentation

🏁 Quick start: Quick start guide,
Types
📑 Advanced: Async safety mode,
Format header collisions,
Compression tips,
Validation/transforms

Credits

tinybuf is based on Guilherme Souza's js-binary