Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Neumenon/cowrie/llms.txt
Use this file to discover all available pages before exploring further.
TypeScript SDK
The TypeScript implementation provides full type safety, works in Node.js and browsers, and has zero dependencies.Installation
- npm
- yarn
- pnpm
npm install cowrie-codec
yarn add cowrie-codec
pnpm add cowrie-codec
Imports
- Gen2 (Full)
- Gen1 (Lightweight)
import { gen2 } from 'cowrie-codec';
// Or direct import:
import { encode, decode, Value } from 'cowrie-codec/gen2';
import { gen1 } from 'cowrie-codec';
// Or direct import:
import { encode, decode } from 'cowrie-codec/gen1';
Basic Usage
Gen2: Encode & Decode
import { gen2 } from 'cowrie-codec';
// From plain objects
const data = gen2.encode({
name: 'Alice',
age: 30,
score: 98.5,
});
// Or using Value API
const val = gen2.SJ.object([
['name', gen2.SJ.string('Alice')],
['age', gen2.SJ.int64(30)],
['score', gen2.SJ.float64(98.5)],
]);
const encoded = gen2.encode(val);
Gen1: Lightweight Encoding
import { gen1 } from 'cowrie-codec';
// Encode any JSON-compatible data
const data = gen1.encode({
name: 'Alice',
scores: [1.0, 2.0, 3.0],
});
// Decode to JavaScript types
const result = gen1.decode(data);
console.log(result.name); // "Alice"
Type System
Creating Values (Gen2)
import { gen2 } from 'cowrie-codec';
const { SJ } = gen2;
// Scalars
const nullVal = SJ.null();
const boolVal = SJ.bool(true);
const intVal = SJ.int64(42);
const uintVal = SJ.uint64(100);
const floatVal = SJ.float64(3.14);
const strVal = SJ.string('hello');
const bytesVal = SJ.bytes(new Uint8Array([1, 2]));
ML Types
import { gen2, DType } from 'cowrie-codec';
const { SJ } = gen2;
// Tensor
const tensorData = new Float32Array([1.0, 2.0, 3.0, 4.0]);
const tensor = SJ.tensor(
DType.FLOAT32,
[2, 2], // shape
new Uint8Array(tensorData.buffer),
);
// Image
const imageData = new Uint8Array([/* JPEG bytes */]);
const img = SJ.image(
'jpeg',
1920, // width
1080, // height
imageData,
);
// Audio
const audioData = new Uint8Array([/* PCM samples */]);
const audio = SJ.audio(
'pcm_int16',
44100, // sample rate
2, // channels
audioData,
);
Graph Types
import { gen2 } from 'cowrie-codec';
const { SJ } = gen2;
// Node
const node = SJ.node(
'person_42',
['Person', 'Employee'],
SJ.object([
['name', SJ.string('Alice')],
['age', SJ.int64(30)],
]),
);
// Edge
const edge = SJ.edge(
'person_42',
'company_1',
'WORKS_AT',
SJ.object([
['since', SJ.int64(2020)],
]),
);
// Graph Shard
const shard = SJ.graphShard(
[node],
[edge],
SJ.object([['version', SJ.int64(1)]]),
);
Type Guards
import { gen2, Value } from 'cowrie-codec';
function processValue(val: Value) {
if (val.type === 'string') {
console.log(val.value.toUpperCase());
} else if (val.type === 'int64') {
console.log(val.value * 2);
} else if (val.type === 'array') {
val.items.forEach(item => processValue(item));
} else if (val.type === 'object') {
Object.entries(val.members).forEach(([key, value]) => {
console.log(`${key}:`, value);
});
} else if (val.type === 'tensor') {
console.log('Tensor shape:', val.dims);
}
}
JSON Bridge
import { gen2 } from 'cowrie-codec';
const val = gen2.SJ.object([
['name', gen2.SJ.string('Alice')],
['age', gen2.SJ.int64(30)],
]);
const jsonStr = gen2.toJSON(val);
console.log(jsonStr); // {"name":"Alice","age":30}
Automatic Type Conversion
import { gen2 } from 'cowrie-codec';
// JavaScript objects are automatically converted
const data = gen2.encode({
name: 'Alice',
age: 30,
scores: [98.5, 87.3, 92.1],
active: true,
metadata: null,
});
// Use fromAny for explicit conversion
const val = gen2.fromAny({
name: 'Alice',
age: 30,
});
Browser Usage
Fetch API
import { gen2 } from 'cowrie-codec';
// Send Cowrie data
const payload = gen2.encode({
action: 'update',
data: { id: 123, name: 'Alice' },
});
const response = await fetch('/api/endpoint', {
method: 'POST',
headers: {
'Content-Type': 'application/x-cowrie',
},
body: payload,
});
// Receive Cowrie data
const responseData = new Uint8Array(await response.arrayBuffer());
const result = gen2.decode(responseData);
Web Workers
// worker.ts
import { gen2 } from 'cowrie-codec';
self.onmessage = (e: MessageEvent<Uint8Array>) => {
const data = gen2.decode(e.data);
// Process data
const result = process(data);
// Send back encoded result
const encoded = gen2.encode(result);
self.postMessage(encoded, [encoded.buffer]);
};
// main.ts
const worker = new Worker('worker.ts');
const data = gen2.encode({ task: 'compute', values: [1, 2, 3] });
worker.postMessage(data, [data.buffer]);
Node.js Usage
File I/O
import { gen2 } from 'cowrie-codec';
import { readFile, writeFile } from 'fs/promises';
// Write
const data = gen2.encode({ name: 'Alice', age: 30 });
await writeFile('data.cowrie', data);
// Read
const fileData = await readFile('data.cowrie');
const result = gen2.decode(fileData);
HTTP Server
import { createServer } from 'http';
import { gen2 } from 'cowrie-codec';
const server = createServer(async (req, res) => {
if (req.method === 'POST') {
const chunks: Uint8Array[] = [];
for await (const chunk of req) {
chunks.push(chunk);
}
const data = Buffer.concat(chunks);
// Decode request
const payload = gen2.decode(data);
// Process and encode response
const result = process(payload);
const response = gen2.encode(result);
res.writeHead(200, { 'Content-Type': 'application/x-cowrie' });
res.end(response);
}
});
server.listen(3000);
Error Handling
import { gen2, SecurityLimitExceeded } from 'cowrie-codec';
try {
const result = gen2.decode(data);
// Process result
} catch (error) {
if (error instanceof SecurityLimitExceeded) {
console.error('Security limit exceeded:', error.message);
} else if (error instanceof Error) {
console.error('Decode error:', error.message);
}
}
Security Options
import { gen2, DecodeOptions } from 'cowrie-codec';
const options: DecodeOptions = {
maxDepth: 500,
maxArrayLen: 1_000_000,
maxObjectLen: 100_000,
maxStringLen: 10_000_000,
maxBytesLen: 100_000_000,
};
const result = gen2.decode(data, options);
TypeScript Types
Value Types
import { Value, Type } from 'cowrie-codec/gen2';
type JsonValue =
| null
| boolean
| number
| bigint
| string
| Uint8Array
| JsonValue[]
| { [key: string]: JsonValue };
function processValue(val: Value): void {
switch (val.type) {
case Type.String:
console.log('String:', val.value);
break;
case Type.Int64:
console.log('Int64:', val.value);
break;
case Type.Array:
console.log('Array length:', val.items.length);
break;
case Type.Object:
console.log('Object keys:', Object.keys(val.members));
break;
}
}
Generic Types
import { gen2, Value } from 'cowrie-codec';
interface User {
name: string;
age: number;
email: string;
}
function encodeUser(user: User): Uint8Array {
return gen2.encode(user);
}
function decodeUser(data: Uint8Array): User {
const result = gen2.decode(data);
return result as User; // Type assertion
}
Advanced Features
Custom Encoders
import { gen2 } from 'cowrie-codec';
class CustomData {
constructor(
public id: number,
public name: string,
) {}
toCowrie() {
return gen2.SJ.object([
['id', gen2.SJ.int64(this.id)],
['name', gen2.SJ.string(this.name)],
['_type', gen2.SJ.string('CustomData')],
]);
}
static fromCowrie(val: Value): CustomData {
if (val.type !== 'object') {
throw new Error('Expected object');
}
return new CustomData(
val.members.id.value as number,
val.members.name.value as string,
);
}
}
const data = new CustomData(123, 'Alice');
const encoded = gen2.encode(data.toCowrie());
const decoded = CustomData.fromCowrie(gen2.decode(encoded));
Batch Operations
import { gen2 } from 'cowrie-codec';
// Encode multiple items
const items = Array.from({ length: 1000 }, (_, i) => ({
id: i,
name: `user_${i}`,
}));
const encoded = items.map(item => gen2.encode(item));
// Decode multiple items
const decoded = encoded.map(data => gen2.decode(data));
Performance Tips
- Use Gen1 for simple data: Faster and smaller for JSON-like data
-
Reuse Uint8Array buffers: Pre-allocate for better performance
const buffer = new Uint8Array(1024 * 1024); // 1MB buffer -
Transfer ownership in workers: Use transferable objects
worker.postMessage(data, [data.buffer]); - Batch encode operations: Process multiple items together
- Use TypedArrays: Faster than regular arrays for numeric data
Examples
Complete Example
import { gen2 } from 'cowrie-codec';
interface UserData {
user: {
name: string;
id: number;
};
scores: number[];
embedding: Float32Array;
active: boolean;
}
function main() {
// Create data
const data: UserData = {
user: {
name: 'Alice',
id: 12345,
},
scores: [98.5, 87.3, 92.1],
embedding: new Float32Array([0.1, 0.2, 0.3]),
active: true,
};
// Encode
const encoded = gen2.encode(data);
console.log(`Encoded size: ${encoded.length} bytes`);
// Decode
const decoded = gen2.decode(encoded);
// Process
if (decoded.type === 'object') {
console.log('User:', decoded.members.user);
console.log('Scores:', decoded.members.scores);
}
}
main();
React Integration
import { useState, useEffect } from 'react';
import { gen2 } from 'cowrie-codec';
function DataComponent() {
const [data, setData] = useState(null);
useEffect(() => {
fetch('/api/data')
.then(res => res.arrayBuffer())
.then(buffer => gen2.decode(new Uint8Array(buffer)))
.then(setData);
}, []);
return <div>{JSON.stringify(data)}</div>;
}