Files
bennc/README.md
Jack Hadrill 68f31018ef
All checks were successful
CI / build (push) Successful in 17s
CI / publish (push) Successful in 15s
style: standardize quotation marks and formatting in README.md
2025-09-06 19:36:14 +01:00

6.0 KiB

BENNC-JS

Build Status

A TypeScript implementation of the BENNC (Butlersaurus Ephemeral No NONCEnse Chat) protocol specification. This library provides both low-level protocol utilities and a high-level client for connecting to BENNC chat servers via WebSocket.

Features

  • Complete BENNC Protocol Support: All message types (0x0000-0xFFFF) including subscribe, basic chat, user data, keepalive, history, and unsubscribe
  • High-Level Client: BenncClient class with automatic reconnection and event-driven architecture
  • Browser & Node.js Compatible: Works in modern browsers and Node.js environments
  • TypeScript First: Full type safety with comprehensive TypeScript definitions
  • Encryption Support: Built-in Romulus-M AEAD encryption for secure messaging
  • Automatic Reconnection: Configurable backoff strategies (constant, exponential)
  • Small Bundle Size: Minimal dependencies and efficient implementation

Installation

npm install @3t/bennc

Quick Start

import { BenncClient, MessageTypes } from "@3t/bennc";

const client = new BenncClient({
  url: "wss://your-bennc-server.com",
  autoReconnect: true,
  reconnectBackoff: "exponential",
  reconnectDelay: 1000,
});

// Listen for events
client.addEventListener("connected", () => {
  console.log("Connected to BENNC server");

  // Subscribe to basic messages
  client.subscribe(MessageTypes.Basic);
});

client.addEventListener("message:1", (event) => {
  const { senderId, data } = event.detail;
  console.log(`Message from ${senderId}:`, new TextDecoder().decode(data));
});

client.addEventListener("disconnected", (event) => {
  console.log("Disconnected:", event.detail);
});

// Connect to server
await client.connect();

// Send a message
client.sendBasicMessage("Hello, BENNC!");

Using Low-Level Protocol Functions

import { packers, unpackers, MessageTypes } from "@3t/bennc";

// Pack a basic message
const messageData = new TextEncoder().encode("Hello World");
const packet = packers[MessageTypes.Basic](messageData);

// Unpack incoming message
const incomingMessage = unpackers[MessageTypes.Basic](receivedData);

API Reference

BenncClient

Constructor Options

interface BenncClientOptions {
  url: string; // WebSocket server URL
  protocols?: string[]; // WebSocket protocols
  autoReconnect?: boolean; // Enable auto-reconnection (default: true)
  reconnectBackoff?: "constant" | "exponential"; // Backoff strategy (default: 'exponential')
  reconnectDelay?: number; // Reconnection delay in ms (default: 1000)
  maxReconnectAttempts?: number; // Max reconnection attempts (default: 10)
}

Methods

  • connect(): Promise<void> - Connect to the BENNC server
  • disconnect(): void - Disconnect from the server
  • isConnected(): boolean - Check connection status
  • subscribe(messageType: MessageTypes): void - Subscribe to message type
  • unsubscribe(messageType: MessageTypes): void - Unsubscribe from message type
  • sendBasicMessage(message: string, key?: Uint8Array): void - Send encrypted chat message
  • sendUserDataRequest(username: string, colour: Color, clientId: string, key?: Uint8Array): void - Request user data
  • sendUserDataResponse(username: string, colour: Color, clientId: string, key?: Uint8Array): void - Respond with user data
  • sendKeepalive(): void - Send keepalive message
  • requestHistory(): void - Request message history

Events

The client extends EventTarget and emits the following events:

  • connected - Successfully connected to server
  • disconnected - Disconnected from server (detail: {code, reason})
  • reconnecting - Attempting to reconnect
  • error - Connection or protocol error (detail: error object)
  • packet - Raw incoming packet (detail: packet object)
  • message - Parsed message (detail: {messageType, senderId, data})
  • message:${messageType} - Specific message type events (detail: {senderId, data})
  • unknown-message - Unknown message type received
  • parse-error - Error parsing incoming message

Message Types

enum MessageTypes {
  Subscribe = 0x0000,
  Basic = 0x0001,
  UserDataRequest = 0x0002,
  UserDataResponse = 0x0003,
  Keepalive = 0x0005,
  GetHistory = 0xfffe,
  Unsubscribe = 0xffff,
}

Protocol Constants

const MAX_DATA_LENGTH = 1000; // Maximum data payload size
const DEFAULT_KEY: Uint8Array; // Default encryption key

Build

To build the BENNC-JS library from source:

$ git clone <repository-url>
$ cd bennc-js
$ npm install
$ npm run build

The build output will be saved to the dist directory.

Protocol Details

BENNC uses a binary protocol with the following message structure:

Client → Server: [Type(2)|Length(2)|Data(0-1000)] Server → Client: [Type(2)|SenderId(4)|Length(2)|Data(0-1000)]

  • All integers are big-endian
  • Maximum data payload is 1000 bytes (including encryption overhead)
  • Encrypted message types (0x0001, 0x0002, 0x0003) use Romulus-M AEAD with 16-byte nonces
  • Reserved sender IDs: 0xFFFFFF00-0xFFFFFFFF

Development

Requirements: Node.js LTS and npm

Commands

# Install dependencies
npm install

# Run tests
npm run test

# Lint code
npm run lint

# Format code
npm run format

# Build library
npm run build

Visual Studio Code

This repository includes VS Code configuration for debugging and testing. Use Ctrl+Shift+B (or ⇧⌘B) to run the build task.

Unit tests use Jest with VS Code support via the Jest extension.

License

ISC License - see package.json for details.

Contributing

This is part of the BENNC protocol ecosystem. Please refer to the BENNC specification for protocol details.