typeshrink
v1.0.0
Published
Semantic JSON minification system with bidirectional encoding/decoding
Maintainers
Readme
typeshrink
A semantic JSON minification library that transforms verbose property keys into deterministic short codes for reduced payload sizes.
Features
- Bidirectional encoding/decoding - Lossless compression and restoration
- Blueprint pattern - Single source of truth for schema and types
- DJB2 hashing - Fast, deterministic key generation
- Collision detection - Fail-fast mechanism prevents data corruption
- Type safety - Full TypeScript support with inferred types
- ~30% size reduction - Typical compression on JSON payloads
Installation
npm install typeshrinkQuick Start
import { createMinifier } from 'typeshrink';
// Define your schema blueprint (this is the source of truth)
const SCHEMA_BLUEPRINT = {
note: '',
data: {
address1: '',
address2: '',
city: '',
additional_fields: { cpf: '' }
},
cost: {
total_cost: 0,
shipping_cost: 0
}
};
// Create a minifier instance
const minifier = createMinifier(SCHEMA_BLUEPRINT);
// Your data
const payload = {
note: 'Express delivery',
data: {
address1: '123 Main Street',
address2: 'Apt 4B',
city: 'New York',
additional_fields: { cpf: '123.456.789-00' }
},
cost: {
total_cost: 150.00,
shipping_cost: 15.00
}
};
// Encode for transmission/storage
const minified = minifier.encode(payload);
// { "n7k": "Express delivery", "dJ2": { "aX9": "123 Main Street", ... } }
// Decode back to original
const restored = minifier.decode(minified);
// Full original payload with types preservedAPI
createMinifier<T>(blueprint, options?)
Creates a minifier instance from a schema blueprint.
Parameters:
blueprint: T- Object defining the schema structureoptions?: MinifierOptions- Optional configuration
Options:
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| seed | number | 5381 | Hash seed (change to resolve collisions) |
| strict | boolean | false | Throw on unknown keys during encoding |
Returns: Minifier<T> with methods:
encode(data: T): JsonValue- Minify datadecode(data: JsonValue): T- Restore datagetKeyMaps(): KeyMaps- Get encode/decode lookup tablesgetBlueprint(): T- Get original blueprintgetKeys(): string[]- Get all extracted keys
Handling Collisions
If two keys hash to the same short code, a CollisionError is thrown at initialization:
import { createMinifier, CollisionError } from 'typeshrink';
try {
const minifier = createMinifier(blueprint);
} catch (error) {
if (error instanceof CollisionError) {
console.log(`Collision: "${error.key1}" and "${error.key2}" -> "${error.shortKey}"`);
// Solution: Change the seed or rename one of the keys
}
}
// Resolve by changing the seed
const minifier = createMinifier(blueprint, { seed: 12345 });How It Works
- Blueprint Analysis - Recursively extracts all unique keys from your schema
- Hash Generation - Uses DJB2 algorithm to create 3-char codes:
[FirstChar][Hash1][Hash2] - Collision Check - Validates no two keys map to the same code (fail-fast)
- Encoding - Replaces keys with short codes during
encode() - Decoding - Restores original keys during
decode()
Using with CBOR
For maximum compression, combine typeshrink with CBOR (Concise Binary Object Representation). This gives you both key minification and binary encoding.
npm install cbor-ximport { createMinifier } from 'typeshrink';
import { encode as cborEncode, decode as cborDecode } from 'cbor-x';
const SCHEMA = {
user: { name: '', email: '' },
items: [{ id: 0, price: 0 }],
total: 0
};
const minifier = createMinifier(SCHEMA);
// === ENCODING (before transmission/storage) ===
function compress(data: typeof SCHEMA): Buffer {
const minified = minifier.encode(data); // Shorten keys
return cborEncode(minified); // Binary encode
}
// === DECODING (after receiving/reading) ===
function decompress(buffer: Buffer): typeof SCHEMA {
const minified = cborDecode(buffer); // Binary decode
return minifier.decode(minified); // Restore keys
}
// Example usage
const payload = {
user: { name: 'John Doe', email: '[email protected]' },
items: [
{ id: 1, price: 29.99 },
{ id: 2, price: 49.99 }
],
total: 79.98
};
const compressed = compress(payload);
const restored = decompress(compressed);
// Size comparison
const jsonSize = Buffer.byteLength(JSON.stringify(payload));
const compressedSize = compressed.length;
console.log(`JSON: ${jsonSize} bytes → CBOR+typeshrink: ${compressedSize} bytes`);
// Typical: 50-60% total reductionCompression Comparison
| Format | Typical Size | Reduction | |--------|-------------|-----------| | Raw JSON | 100% | baseline | | typeshrink + JSON | ~70% | ~30% | | Raw CBOR | ~75% | ~25% | | typeshrink + CBOR | ~50% | ~50% |
[!TIP] CBOR is particularly effective for payloads with numbers, booleans, and binary data since it uses a more compact binary representation than JSON's text format.
Performance
Typical results on JSON payloads:
| Metric | Value | |--------|-------| | Compression ratio | 20-40% reduction | | Encoding speed | < 1ms for typical payloads | | Hash collisions | Extremely rare (resolvable via seed) |
Development
# Install dependencies
npm install
# Run tests
npm test
# Build
npm run buildLicense
MIT
