BENNC-JS
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:
BenncClientclass 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
Using the BenncClient (Recommended)
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 serverdisconnect(): void- Disconnect from the serverisConnected(): boolean- Check connection statussubscribe(messageType: MessageTypes): void- Subscribe to message typeunsubscribe(messageType: MessageTypes): void- Unsubscribe from message typesendBasicMessage(message: string, key?: Uint8Array): void- Send encrypted chat messagesendUserDataRequest(username: string, colour: Color, clientId: string, key?: Uint8Array): void- Request user datasendUserDataResponse(username: string, colour: Color, clientId: string, key?: Uint8Array): void- Respond with user datasendKeepalive(): void- Send keepalive messagerequestHistory(): void- Request message history
Events
The client extends EventTarget and emits the following events:
connected- Successfully connected to serverdisconnected- Disconnected from server (detail:{code, reason})reconnecting- Attempting to reconnecterror- 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 receivedparse-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.