Skip to content

@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.

License

Notifications You must be signed in to change notification settings

atlassian-labs/lexicographic-keys

@lexicographic/keys

Atlassian license npm version PRs Welcome

@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.

Key Features

  • 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

Why @lexicographic/keys?

@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

Usage

Basic Encoding and Decoding

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']

Lexicographical Ordering

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#"
// ]

Prefix Matching

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#"
// ]

Working with Negative Numbers

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

Installation

yarn add @lexicographic/keys

Or with npm:

npm install @lexicographic/keys

API Documentation

encode(...segments)

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

decode(input)

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 Validation

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

Number Support

  • Supports all safe integers (Number.MIN_SAFE_INTEGER to Number.MAX_SAFE_INTEGER)
  • Negative numbers sort before positive numbers
  • Zero is treated as a positive number

Tests

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

Contributions to @lexicographic/keys are welcome! Please see CONTRIBUTING.md for details.

License

Copyright (c) 2025 Atlassian US., Inc. Apache 2.0 licensed, see LICENSE file.

With ❤️ from Atlassian

About

@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.

Topics

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Packages

No packages published