https://github.com/cmdruid/buffy
A compact byte manipulation tool.
https://github.com/cmdruid/buffy
Last synced: 5 months ago
JSON representation
A compact byte manipulation tool.
- Host: GitHub
- URL: https://github.com/cmdruid/buffy
- Owner: cmdruid
- License: mit
- Created: 2025-01-04T09:09:11.000Z (over 1 year ago)
- Default Branch: master
- Last Pushed: 2025-09-18T06:34:46.000Z (9 months ago)
- Last Synced: 2025-11-23T17:11:46.805Z (7 months ago)
- Language: TypeScript
- Size: 150 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE.md
Awesome Lists containing this project
README
# @vbyte/buff
A compact swiss-army-knife for byte manipulation.
Features:
* Move between data formats with ease!
* `Buff` objects are instance of `Uint8Array`.
* Prepend, append, sort, split, chunk, join, and more!
* Convert blobs of data into consumable streams.
* Uses `DataView.setUint8` for ultra-fast performance.
* Supports endianness for all the things!
## How to Import
This library is designed to support classic and modern ESM imports, both in nodejs and a browser environment.
Example install via package manager:
```bash
npm install @vbyte/buff
bun install @vbyte/buff
yarn add @vbyte/buff
```
Classic import into a nodejs project:
```ts
const { Buff, Stream } = require('@vbyte/buff')
```
Modern import into an nodejs project:
```ts
import { Buff, Stream } from '@vbyte/buff'
```
Classic import into a browser-based project:
```html
const { Buff, Stream } = window.buff
```
Modern import into a browser-based project:
```html
import { Buff, Stream } from "https://unpkg.com/@vbyte/buff/dist/module.mjs"
```
## How to Use
The `Buff` class is an extension of the base `Uint8Array` class. It provides the same default functionality of a Uint8Array, and can be used as a drop-in replacement for Uint8Array. Typescript will treat Buff as a Uint8Array object.
```ts
import { Buff, Stream } from '@vbyte/buff'
// Buffable covers value types that are convertable to Uint8Array.
type Buffable = Bytes | number | bigint
// Bytes covers hex strings, byte arrays, Buff, and Stream objects.
type Bytes = string | Uint8Array | Buff | Stream
// You can optionally specify the endianness of data.
type Endian = 'le' | 'be'
const buffer = new Buff (
data : Buffable | ArrayBuffer,
size ?: number, // Specify the size of the array (for padding)
endian ?: Endian // Specify the endianness of the array.
)
```
You can convert from many different types and formats into a `Buff` object.
```ts
Buff
.big (data : bigint, size ?: number, endian ?: Endian) => Buff
.bin (data : string, size ?: number, endian ?: Endian) => Buff
.bytes (data : Bytes, size ?: number, endian ?: Endian) => Buff
.hex (data : string, size ?: number, endian ?: Endian) => Buff
.json (data : T, replacer ?: Replacer) => Buff
.num (data : number, size ?: number, endian ?: Endian) => Buff
.str (data : string, size ?: number, endian ?: Endian) => Buff
.u8a (data : Uint8Array, size ?: number, endian ?: Endian) => Buff
```
With `Buff`, you have access to an extensive API for converting between formats.
```ts
const buffer = new Buff(data)
/* Quickly convert into many formats using getters. */
buffer
.arr => number[] // Convert to a number array.
.big => bigint // Convert to a BigInt.
.bin => string // Convert to a binary string.
.hex => string // Convert to a hex string.
.num => number // Convert to a Number.
.str => string // Convert to a UTF8 string.
.u8a => Uint8Array // Convert to a plain Uint8Array.
/* There are a few export methods that support extra params. */
buffer
.to_arr : () => number[]
.to_big : (endian ?: Endian) => bigint
.to_bin : () => string
.to_hex : (endian ?: Endian) => string
.to_json : (reviver ?: Reviver) => T
.to_num : (endian ?: Endian) => number
.to_str : () => string
.to_u8a : () => Uint8Array
```
In addition to format conversion, you can perform many other convenient tasks.
```ts
Buff
// Same as Uint8Array.from(), but returns a Buff object.
.from (data : Uint8Array | number[]) => Buff
// Same as Uint8Array.of(), but returns a Buff object.
.of (...data : number[]) => Buff
// Join together multiple arrays of bytes.
.join (array : Buffable[]) => Buff
// Sort multiple arrays of bytes in lexicographic order.
.sort (arr : Buffable[], size ?: number) => Buff[]
// Split bytes into equal-sized chunks.
.chunk (payload : Bytes, chunk_size : number, total_size : number) => Buff[]
// Return a buffer object with random data (uses webcrypto).
.random (size ?: number) => Buff
// Return a buffer containing the current Unix timestamp (4 bytes).
.now () => Buff
// Converts a number into a 'varint' for byte streams.
.create_varint (num : number, endian ?: Endian) => Buff
// Check if two Buffable values are equal.
.is_equal (a : Buffable, b : Buffable) => boolean
// Check if a value is valid bytes (hex string or Uint8Array).
.is_bytes (value : unknown) => boolean
// Check if a string is valid hexadecimal.
.is_hex (value : unknown) => boolean
const buffer = new Buff(data)
buffer
// Append data to your buffer object.
.append (data : Buffable) => Buff
// Prepend data to your buffer object.
.prepend (data : Buffable) => Buff
// Check if this buffer equals another.
.equals (data : Buffable) => boolean
// Prepend a varint-encoded length prefix to this buffer.
.prefix_varint (endian ?: Endian) => Buff
// Same as Uint8Array.reverse(), but returns this Buff (chainable).
.reverse () => this
// Identical to Uint8Array.set() method.
.set (array : ArrayLike, offset ?: number) => void
// Same as Uint8Array.slice(), but returns a Buff object.
.slice (start ?: number, end ?: number) => Buff
// Same as Uint8Array.subarray(), but returns a Buff object.
.subarray (begin ?: number, end ?: number) => Buff
// Returns the hex representation (used by JSON.stringify).
.toJSON () => string
// Returns the hex representation as a string.
.toString () => string
```
The `Stream` class will take a blob of data and allow you to consume it byte-per-byte.
```ts
import { Stream } from '@vbyte/buff'
// Convert data into a stream object.
const stream = new Stream(data)
stream
.size => number // Current number of bytes remaining in the stream.
.data => Uint8Array // Current stream data.
stream
// Reads x number of bytes, does not consume the stream.
.peek (size : number) => Buff
// Reads x number of bytes, consumes the stream.
.read (size : number) => Buff
// Reads the next bytes(s) as a varint, returns the number value.
.read_varint (endian ?: Endian) => number
```
## Migration Guide
If upgrading from an earlier version, note the following API changes:
- `Buff.blob()` renamed to `Buff.chunk()` - splits bytes into equal-sized chunks
- `Buff.varint()` renamed to `Buff.create_varint()` - creates varint-encoded buffer
## Security Considerations
- **Cryptographic Random:** `Buff.random()` uses the Web Crypto API (`crypto.getRandomValues`) for cryptographically secure random bytes, with fallback to Node.js `crypto.randomBytes` in legacy environments
- **Input Validation:** All public methods validate inputs. Hex strings are checked for valid characters and even length. Byte arrays are validated to contain integers in the 0-255 range
- **Integer Safety:** Number conversions check against `Number.MAX_SAFE_INTEGER` and `Number.MIN_SAFE_INTEGER` to prevent precision loss
- **Custom Error Types:** The library exports typed error classes (`ValidationError`, `HexValidationError`, `ByteRangeError`, `IntegerBoundsError`, `SizeError`) for precise error handling
- **No Dependencies:** Zero production dependencies minimizes supply chain risk
## Bugs / Issues
Please feel free to post any questions or bug reports on the issues page!
## Development / Testing
This project uses `typescript` for development, `tape` for testing, and `rollup` for release bundles.
```bash
npm test
npm run release
```
## Contributions
All contributions are welcome!
## License
Use this code however you like! No warranty!