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.

Description
No description provided
Readme ISC 456 KiB
v1.0.3 Latest
2025-09-06 18:41:49 +00:00
Languages
TypeScript 100%