npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

jigsaw-protocol

v0.1.1

Published

JavaScript/TypeScript client for the Jigsaw Protocol v1.0.0

Readme

Jigsaw Protocol JS

JavaScript/TypeScript bindings for the Jigsaw Protocol v1.0.0.

Jigsaw is a schema-negotiation protocol that replaces JSON with compact MessagePack payloads once both peers have agreed on a schema. This library wraps jigsaw-rust via:

Installation

npm install jigsaw-protocol

Pre-built binaries for common platforms are included in the npm package. Building from source requires a Rust toolchain (see Building from source).

Quick Start

Node.js

import { Session } from "jigsaw-protocol";

// Two in-process sessions wired together for illustration.
// In production, wire the Uint8Array frames over WebSocket / TCP / etc.
const alice = new Session(nativeHandle(true)); // initiator
const bob = new Session(nativeHandle(false)); // responder

// Alice starts the handshake.
let frames = alice.start();

// Shuttle frames until steady state.
while (frames.length) {
  const replies: Uint8Array[] = [];
  for (const frame of frames) {
    const r = bob.receive(frame);
    replies.push(...r);
  }
  frames = [];
  for (const frame of replies) {
    const r = alice.receive(frame);
    frames.push(...r);
  }
}

// Both peers are now in S3_STEADY. Alice sends an object.
const outFrames = alice.sendObject({ userId: 42, name: "Alice" });
// Bob receives it:
for (const frame of outFrames) {
  bob.receive(frame);
}

The nativeHandle helper above is a thin wrapper over the compiled native addon. In a typical application you would import it directly from the built artifact:

// Node.js native addon (built by `npm run build:native`)
const { JsSession } = require("./jigsaw-protocol-native.node");

function nativeHandle(initiator: boolean) {
  return new JsSession(initiator);
}

Browser (WASM)

<script type="module">
  import init, { WasmSession } from "./dist/wasm/jigsaw_protocol_wasm.js";

  await init();

  const alice = new WasmSession(true);
  const bob = new WasmSession(false);

  let frames = alice.start();

  while (frames.length) {
    const replies = [];
    for (const frame of frames) replies.push(...bob.receive(frame));
    frames = [];
    for (const frame of replies) frames.push(...alice.receive(frame));
  }

  alice.send_object(JSON.stringify({ event: "click", x: 100, y: 200 }));
</script>

API Reference

Session (TypeScript wrapper)

The Session class in js/src/session.ts wraps a native or WASM session handle and provides a typed interface.

new Session(handle: NativeSessionHandle)

| Method / Property | Signature | Description | | ----------------- | ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------- | | start() | () => Uint8Array[] | Begin the session. Returns framed wire messages to send. Call once before anything else. | | receive(data) | (data: Uint8Array) => Uint8Array[] | Feed one framed wire message received from the peer. Returns zero or more messages to send in reply. | | sendObject(obj) | (obj: Record<string, unknown>) => Uint8Array[] | Send a JSON object. Automatically negotiates the schema. Only valid in S3_STEADY or S2_SCHEMA_SYNC. | | pollTimeouts() | () => Uint8Array[] | Check for expired protocol timers. Call periodically (e.g. every 100 ms). Returns messages to send if a timeout fired. | | state | SessionState (getter) | Current state string: "S0_INIT""S6_CLOSED". | | isClosed | boolean (getter) | true when the session is in the terminal S6_CLOSED state. |

SessionState

type SessionState =
  | "S0_INIT" // not yet started
  | "S1_HANDSHAKE" // HELLO / HELLO_ACK exchange
  | "S2_SCHEMA_SYNC" // schema negotiation
  | "S3_STEADY" // full-speed binary payload exchange
  | "S4_RESYNC" // schema mismatch recovery
  | "S5_FALLBACK_JSON" // temporary plain-JSON mode
  | "S6_CLOSED"; // terminal

Wire framing

Every Uint8Array returned by the library or passed to receive() is a length-prefixed frame:

[ 4-byte big-endian uint32 length ][ payload bytes ]

You must transmit and receive frames atomically (e.g. over a WebSocket message or a framed TCP stream).

JsSchema.computeId (Node.js native)

JsSchema.computeId(fields: string[], refs?: boolean[], refIsArray?: boolean[]): bigint

Computes the xxHash64 schema identifier for a given field list. Useful for debugging or pre-computing IDs.

WasmSchema.compute_id (WASM)

WasmSchema.compute_id(fields: string[], refs?: boolean[], refIsArray?: boolean[]): bigint

Same as above, callable from browser WASM.

Building from Source

Prerequisites

# Install Node dependencies (includes @napi-rs/cli)
npm install

# Build the Node.js native addon
npm run build:native

# Build the WASM bundle
npm run build:wasm

# Compile TypeScript
npm run build:ts

# Build everything at once
npm run build

Output layout

dist/
├── node/          # CommonJS output (for Node.js require)
├── esm/           # ES module output (for bundlers / browsers)
└── wasm/          # wasm-pack output (jigsaw_protocol_wasm_bg.wasm + JS glue)

License

MIT