@lexicographic/keys
is a lexicographical encoding library that converts mixed-type data (strings and numbers) into sortable string keys. This enables efficient range queries and prefix matching in key-value stores\databases (i.e DynamoDB), and other systems that rely on lexicographical ordering.
- Lexicographical Sorting: Encoded strings sort in the same order as their original values
- Mixed Type Support: Handles both strings and numbers in the same key
- Prefix Matching: Supports efficient prefix-based queries
- Type Safety: Full TypeScript support with comprehensive type definitions
- Zero Dependencies: Lightweight pure JavaScript implementation
@lexicographic/keys
offers several advantages over alternative encoding libraries like charwise:
- Human-Readable Output: Generated keys are a lot more readable
- Proper Integer Handling: Treats integers as integers rather than converting them to floats, preserving precision and natural sorting
- Built-in Prefix Support: Every encoded identifier naturally serves as a prefix for hierarchical queries, enabling efficient range scans
- Focused API: Simple surface area supporting only strings and integers, reducing complexity and potential errors
import { encode, decode } from '@lexicographic/keys';
// Encode mixed types into a sortable string
const key = encode('user', 42, 'profile');
console.log(key); // "[S]user#[P]0000000000000042#[S]profile#"
// Decode back to original values
const values = decode(key);
console.log(values); // ['user', 42, 'profile']
import { encode } from '@lexicographic/keys';
// Create keys that sort correctly
const keys = [
encode('app', 'deployment', 10),
encode('app', 'deployment', 2),
encode('app', 'deployment', 1),
encode('app', 'event', 1)
];
// Sort lexicographically
const sorted = keys.sort();
console.log(sorted);
// [
// "[S]app#[S]deployment#[P]0000000000000001#",
// "[S]app#[S]deployment#[P]0000000000000002#",
// "[S]app#[S]deployment#[P]0000000000000010#",
// "[S]app#[S]event#[P]0000000000000001#"
// ]
import { encode } from '@lexicographic/keys';
// Create a prefix for queries
const prefix = encode('app', 'deployment');
// Generate some keys
const allKeys = [
encode('app', 'deployment', 1, 'data'),
encode('app', 'deployment', 2, 'config'),
encode('app', 'event', 1, 'log'),
encode('other', 'service', 1)
];
// Find all keys that start with the prefix
const matchingKeys = allKeys.filter(key => key.startsWith(prefix));
console.log(matchingKeys);
// [
// "[S]app#[S]deployment#[P]0000000000000001#[S]data#",
// "[S]app#[S]deployment#[P]0000000000000002#[S]config#"
// ]
import { encode, decode } from '@lexicographic/keys';
// Negative numbers are supported and sort correctly
const keys = [
encode('metric', -100),
encode('metric', -1),
encode('metric', 0),
encode('metric', 1),
encode('metric', 100)
];
console.log(keys.sort());
// Negative numbers will sort before positive numbers
yarn add @lexicographic/keys
Or with npm:
npm install @lexicographic/keys
Encodes multiple segments into a lexicographically sortable string.
Parameters:
...segments
- Variable number of string or number arguments
Returns:
string
- The encoded string with segments separated by '#'
Throws:
Error
- When a segment is not a string or number
Decodes an encoded string back into its original segments.
Parameters:
input
-string
- The encoded string to decode
Returns:
Array<string|number>
- Array of decoded segments
Throws:
Error
- When encountering an invalid segment prefix
String segments must match the pattern: /^[a-zA-Z0-9\-_][a-zA-Z0-9\-_.]*$/
- Must start with alphanumeric, hyphen, or underscore
- Can contain alphanumeric characters, hyphens, underscores, and periods
- Cannot start with a period
- Supports all safe integers (
Number.MIN_SAFE_INTEGER
toNumber.MAX_SAFE_INTEGER
) - Negative numbers sort before positive numbers
- Zero is treated as a positive number
Run the test suite:
yarn test
The library includes comprehensive tests covering:
- Basic encoding/decoding functionality
- Lexicographical sorting behavior
- Prefix matching capabilities
- Error handling
- Edge cases with negative numbers and mixed types
Contributions to @lexicographic/keys
are welcome! Please see CONTRIBUTING.md for details.
Copyright (c) 2025 Atlassian US., Inc. Apache 2.0 licensed, see LICENSE file.