1.0.0-alpha.1 • Published 10 months ago

@jkomyno/capnp-ts v1.0.0-alpha.1

Weekly downloads
-
License
MIT
Repository
github
Last release
10 months ago
      ██████╗ █████╗ ██████╗ ██╗███╗   ██╗
     ██╔════╝██╔══██╗██╔══██╗██║████╗  ██║
     ██║     ███████║██████╔╝╚═╝██╔██╗ ██║
     ██║     ██╔══██║██╔═══╝    ██║╚██╗██║
     ╚██████╗██║  ██║██║        ██║ ╚████║
      ╚═════╝╚═╝  ╚═╝╚═╝        ╚═╝  ╚═══╝
 ██████╗ ██████╗  ██████╗ ████████╗ ██████╗
 ██╔══██╗██╔══██╗██╔═══██╗╚══██╔══╝██╔═══██╗
 ██████╔╝██████╔╝██║   ██║   ██║   ██║   ██║
 ██╔═══╝ ██╔══██╗██║   ██║   ██║   ██║   ██║
 ██║     ██║  ██║╚██████╔╝   ██║   ╚██████╔╝
 ╚═╝     ╚═╝  ╚═╝ ╚═════╝    ╚═╝    ╚═════╝

                         infinitely
                           faster!

-- TypeScript + ESM Edition

This is a TypeScript + ESM implementation of the Cap'n Proto serialization protocol. It provides a TypeScript library and a plugin for the official compiler, capnpc. Start with the Cap'n Proto Introduction for more detailed information on what this is about.

This is a partial rewrite of https://github.com/jdiaz5513/capnp-ts. Why a rewrite? Because:

  • I wanted to use it in a Deno project, but the original version wasn't compatible with Deno (as it was using CommonJS rather than ESM)
  • tap, the test framework used by the original version, doesn't work well with ESM (despite trying to use ts-node/register and "esm": true)
  • The latest compiler plugin available, capnpc-ts@0.7.0, is broken (https://github.com/jdiaz5513/capnp-ts/issues/174)
  • The original version wasn't compatible with TypeScript 4.8+ (https://github.com/jdiaz5513/capnp-ts/issues/177)
  • I plan on sensibly diverging from the original project in a Wasm-oriented direction

Installation

Grab the latest library version from deno:

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

You will need the TypeScript schema compiler as well, globally:

deno install --allow-env --allow-read --allow-write -n capnpc-ts "https://deno.land/x/capnpc/mod.ts"

The schema compiler is a Cap'n Proto plugin and requires the capnpc binary in order to do anything useful; follow the Cap'n Proto installation instructions to install it on your system.

Implementation Notes

These notes are provided for people who are familiar with the C++ implementation, or implementations for other languages. Those who are new to Cap'n Proto may skip this section.

This implementation differs in a big way from the C++ reference implementation: there are no separate Builder or Reader classes. All pointers are essentially treated as Builders.

This has some major benefits for simplicity's sake, but there is a bigger reason for this decision (which was not made lightly). Everything is backed by ArrayBuffers and there is no practical way to prevent mutating the data, even in a dedicated Reader class. The result of such mutations could be disastrous, and more importantly there is no way to reap much performance from making things read-only.

Usage

Compiling Schema Files

Run the following to compile a schema file into TypeScript source code:

capnpc -o ts path/to/myschema.capnp

Running that command will create a file named path/to/myschema.capnp.ts.

To write the compiled source to a different directory:

capnpc -o ts:/tmp/some-dir/ path/to/myschema.capnp

That will generate a file at /tmp/some-dir/path/to/myschema.capnp.ts.

Reading Messages

To read a message, do something like the following:

import * as capnp from "https://deno.land/x/capnp/mod.ts";

import { MyStruct } from "./myschema.capnp.ts";

export function loadMessage(buffer: ArrayBuffer): MyStruct {
  const message = new capnp.Message(buffer);

  return message.getRoot(MyStruct);
}

Building

TODO

Debugging

Some debug trace functionality is provided by the debug library.

To see trace messages in nodejs, export the following environment variable:

export DEBUG='capnp*'

When running in a web browser, use localStorage to enable debug output:

localStorage.debug = "capnp*";

Trace messages can get rather noisy, so tweak the DEBUG variable as you see fit.

All messages also have a handy .dump() method that returns a hex dump of the first 8 KiB for each segment in the message:

> console.log(message.dump());

================
Segment #0
================

=== buffer[64] ===
00000000: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00 ················
00000010: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00 ················
00000020: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00 ················
00000030: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00 ················

License

MIT