created by
Liam Swayne
npm
chrono-client-db

ChronoClientDB

Client-side temporal database stored as a single string

Query rows
Insert row
Update rows
Remove rows
Edit metadata
Current data
String encoding of the entire database
Includes the schema, all metadata, and all rows
String encoding of database including full-fidelity history
Includes the schema, all metadata, all rows, and complete operation history
Time complexity
Operation Time Complexity
query(filterFn) $O(n)$ where $n$ is the number of rows
insert(row) $O(1)$ amortized for row insertion, $O(c)$ for validation where $c$ is the number of columns
update(transformFn, max) $O(n \cdot c \cdot O(f))$ where $n$ is the number of rows, $c$ is the number of columns, and $O(f)$ is the time complexity of the transformation function
remove(filterFn, max) $O(n \cdot c \cdot O(f))$ where $n$ is the number of rows, $c$ is the number of columns, and $O(f)$ is the time complexity of the filter function
Compression techniques
1. Variable-length integer encoding (UBInt)
Uses a custom unbounded integer format where each integer is encoded using 2-bit pairs: 01 for bit 0, 10 for bit 1, 11 for bits 11, and 00 as terminator. This eliminates fixed-width overhead for small integers.
2. Custom alphabet encoding for strings
Analyzes all unique characters in each string column (including history) to build a minimal alphabet. Each character is then encoded using $\lceil \log_2(|\text{alphabet}| + 1) \rceil$ bits instead of 8 bits, with 000... as string terminator.
3. Sorted column optimization
Detects when an integer column forms a complete sorted sequence from 0 to $n-1$. In this case, the column values are implicit (equal to row index) and are not encoded at all, saving significant space.
4. Timestamp delta encoding
History operations store only the first timestamp fully; subsequent timestamps are encoded as deltas from the previous timestamp, drastically reducing space for temporal data.
5. Update operation bitmask
For update operations, uses a bitmask to indicate which columns changed, then only encodes the old values for those specific columns rather than storing entire row snapshots.
6. Bit-level LZ77 compression
Applies a custom bit-level LZ77-like compression algorithm that operates directly on bit arrays. Uses 12-bit distance fields (4095-bit lookback window) and 8-bit length fields with hash-based match finding for efficient back-references.
7. Adaptive compression flag
Compares compressed vs uncompressed payload sizes and automatically selects the smaller representation, prefixed with a 1-bit flag. Ensures compression never increases total size.
8. Schema-driven type optimization
Different column types use optimal encodings: UBInt for integers/unix timestamps, custom alphabets for strings, and length-prefixed JSON. The schema defines interpretation, meaning there are no type tags per value.
9. Minimal padding
Only pads to the byte boundary at the very end of the entire encoded stream, maximizing bit-level compression efficiency throughout the encoding process. The entire database contains at most 7 bits of padding in total.
API documentation
new ChronoClientDB(options)
Parameters:
  • options.source (string, optional) - Encoded database string to load existing database
  • options.header (object, required if no source) - Schema definition mapping column names to types: 'UUID-int', 'UUID-int-manual', 'string', 'unix', 'int', 'json'
  • options.history (boolean, required if no source) - Enable operation history tracking for time-travel functionality
  • options.destructiveRewind (boolean, optional, default: true) - If true, rewind operations permanently delete history; if false, rewind operations are themselves recorded in history
  • options.metadata (object, optional) - Arbitrary JSON metadata to store with the database
Returns: ChronoClientDB instance
query(filterFn)
Retrieves rows that match the filter criteria.
Parameters:
  • filterFn (function) - Function that receives a row object and returns true to include the row in results, false to exclude
Returns: Array of row objects (deep copies) that match the filter
insert(row)
Inserts a new row into the database. Auto-generates UUIDs for 'UUID-int' columns.
Parameters:
  • row (object) - Object with values for each column defined in schema. Do not provide values for 'UUID-int' columns (auto-generated). Must provide unique values for 'UUID-int-manual' columns.
Returns: Number - The new total number of rows in the database
update(transformFn, max = Infinity)
Updates rows by applying a transformation function. Only records changed rows in history.
Parameters:
  • transformFn (function) - Function that receives a row object and returns the updated row object. Must return a valid row matching the schema.
  • max (number, optional, default: Infinity) - Maximum number of rows to update. Stops processing after this many updates.
Returns: Number - The actual number of rows that were updated (changed)
remove(filterFn, max = Infinity)
Removes rows that match the filter criteria. Throws error if attempting to remove more than max rows.
Parameters:
  • filterFn (function) - Function that receives a row object and returns true to remove the row, false to keep it
  • max (number, optional, default: Infinity) - Maximum number of rows allowed to be removed. Throws error if filter matches more rows.
Returns: Number - The number of rows that were removed
encode()
Serializes the entire database (schema, metadata, rows, and history) into a compact string representation.
Parameters: None
Returns: String - Compressed, encoded representation of the entire database state
rewind(options)
Reverts the database to a previous state. Requires history to be enabled. In destructive mode, removes rewound operations from history. In non-destructive mode, records the rewind as a new operation.
Parameters:
  • options.time (number, optional) - Unix timestamp in milliseconds. Reverts all operations after this time.
  • options.operations (number, optional) - Number of operations to undo from most recent.
Note: Must provide exactly one of time or operations
Returns: void
getSchema()
Returns the database schema (column definitions).
Parameters: None
Returns: Object - Deep copy of schema mapping column names to types
getMetadata()
Returns the database metadata.
Parameters: None
Returns: Object - Deep copy of the metadata object
setMetadata(newMetadata)
Updates the database metadata.
Parameters:
  • newMetadata (object) - New metadata object to store
Returns: void
getHistory()
Returns the operation history (if history is enabled).
Parameters: None
Returns: Array - Deep copy of operation history in reverse chronological order (newest first)
isHistoryEnabled()
Checks if history tracking is enabled for this database.
Parameters: None
Returns: Boolean - true if history is enabled, false otherwise
getVersion()
Returns the database format version number.
Parameters: None
Returns: Number - Version number of the database format (currently 0)