Skip to main content
Deno 2 is finally here 🎉️
Learn more

Coder

Data encoder and decoder that cares about data types.

Why do I need Coder?

Coder encodes javascript data into a buffer and decodes it back. Therefore data can be sent over the network without losing data types.

  • Supports a lot of types out of the box
  • is extendable

I can do that with JSON, right?

JSON is great, except it doesn’t support a lot of types.

const date = new Date();

const string = JSON.stringify(date); // "2020-02-13T13:16:43.096Z"
JSON.parse(string); // SyntaxError

In comparison Coder supports a lot of different types by default so your data will have the same type after decoding.

import { coder } from "https://deno.land/x/coder/mod.ts";

const date = new Date();
const buffer = coder.encode(date); // ArrayBuffer
coder.decode(buffer); // Date()

But there is messagepack and protocol buffers, right?

Yes, and this project is inspired by messagepack. But Coder is specifically designed between comunicating between client- and server-side javascript. Therefore it only cares about javascript types.

Usage

import { coder } from "https://deno.land/x/coder/mod.ts";

const date = new Date();
const buffer = coder.encode(data);
coder.decode(buffer); // Date()

Supported types

Coder supports lots of types out of the box:

It needs to be discussed what additional types should be supported by default. Some possible candidates are:

Custom DataType Definition

Coder can easily be extended with custom DataTypes.

Example:

1. Define Custom DataType

// SymbolDataType.ts
import { DataType, Decoder, Encoder } from "https://deno.land/x/coder/mod.ts";

export class SymbolDataType extends DataType {
  // The test method returns true if data should be decoded for that type
  test(data: unknown) {
    return typeof data === "Symbol";
  },
  // The encode method transforms the data into a buffer
  encode(encoder: Encoder, data: Symbol) {
    const description = data.description; // get data to encode
    const dataBuffer = encoder.stringToBuffer(description); // convert description to buffer
    const lengthBuffer = encoder.uInt8ToBuffer(dataBuffer.byteLength); // convert length to buffer
    return encoder.combineBuffers(lengthBuffer, dataBuffer); // return combined buffer
  },
  // The decode method transforms the buffer back to a value
  decode(decoder: Decoder) {
    const length = decoder.stepUint8(); // get length
    const description = decoder.stepString(length); // get description
    return Symbol(description); // create Symbol with description
  },
};

2. Set Custom DataType

There are 16 slots reserved for custom DataTypes: 0xf0-0xff. Chose a free one and set the DataType.

import { coder } from "https://deno.land/x/coder/mod.ts";
// import custom DataType
import { SymbolDataType } from "./path/to/SymbolDataType.ts";
// set custom DataType
coder.set(0xf0, SymbolDataType);

That’s it! Now Symbols will be encoded and decoded.

3. Use Custom DataType

const data = { mySymbol: Symbol("foo") };
const buffer = coder.encode(data);
coder.decoder(buffer); // { mySymbol: Symbol(foo) }