@undercroft/pulse-frame
Version:
Low-level WebSocket framing library implementing RFC 6455. Supports payload masking, control frames, and binary/text handling.
116 lines (80 loc) • 3.34 kB
Markdown
# Pulse Frame
`pulse-frame` is a lightweight, zero-dependency WebSocket framing library written in TypeScript. It
implements the WebSocket frame format defined in [RFC 6455, Section 5](https://datatracker.ietf.org/doc/html/rfc6455#section-5),
providing core utilities to parse, validate, and construct frames with full support for masking,
extensions, and control opcodes.
## Features
- Full support for text, binary, continuation, and control frames
- RFC-compliant masking and unmasking logic
- Extension-aware (RSV1/2/3 validation)
- Frame validation (e.g. close codes, control length limits)
- Comprehensive test coverage
## What is WebSocket framing?
WebSocket data is sent in discrete **frames**, not a continuous byte stream. Every frame consists of
a small header and an optional payload. For example:
```
0 1 2 3
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
+-+-+-+-+-------+---------------+-------------------------------+
|F|R|R|R| opcode| Mask | Payload len (7) | (extended + masking) |
+-+-+-+-+-------+---------------+-------------------------------+
```
- **FIN/RSV1/RSV2/RSV3**: Control how data is processed.
- **Opcode**: Tells what kind of data this is (text, binary, ping, etc).
- **Mask**: Whether the data is XOR-masked (required for client-to-server).
- **Payload length**: May be 7, 16, or 64 bits long depending on size.
- **Masking key** (if set) + **payload** follow.
This library helps you construct and parse that structure cleanly.
## Usage
```ts
import {
createFrameFromBuffer,
frameToBuffer,
PulseFrameOpcode,
} from 'pulse-frame';
// Parse an incoming WebSocket frame
const frame = createFrameFromBuffer(rawBuffer);
if (frame.isText()) {
console.log(frame.getPayloadString());
}
// Create a new frame
const outFrame = createFrame({
opcode: PulseFrameOpcode.TEXT,
payloadData: Buffer.from('hello'),
});
const wireBuffer = frameToBuffer(outFrame);
```
## Modules
Each function is organized by responsibility:
- **Parsing**: `createFrameFromBuffer`, `parseHeader`, `readPayloadLength`
- **Building**: `createFrame`, `frameToBuffer`, `packHeaderBytes`
- **Validation**: `validateOpcode`, `validateExtensions`, `validateCloseFramePayload`
- **Masking**: `maskPayload`, `unmaskPayload`, `extractMaskingKey`
- **Splitting**: `extractPayload`, `extractExtensionData`, `extractApplicationData`
## Testing
`pulse-frame` is covered by over 100 unit tests, covering edge cases like:
- Unmasked/masked frame parsing
- Control frame length enforcement
- Payload lengths using 7/16/64-bit representations
- RSV bits with/without extension support
You can run tests via:
```bash
npm run test
```
Or view coverage:
```bash
npm run coverage
```
For more details on the available methods and their usage, please refer to the API documentation or
the source code.
## Contributing
Contributions to the Pulse Frame library are welcome! If you have any issues or suggestions for improvements,
please open an issue or submit a pull request on the GitHub repository.
## License
The Pulse Frame library is licensed under the MIT License. See the LICENSE file for more information.