@vyckr/ttid
v1.2.5
Published
A lightweight, time-based identifier generator that tracks creation, update, and deletion timestamps using a progressive format.
Downloads
46
Maintainers
Readme
TTID (Time-Tagged Identifier)
A lightweight, time-based identifier generator that tracks creation, update, and deletion timestamps using a progressive format.
Overview
TTID creates unique identifiers with a progressive structure:
- Created:
[CREATION_TIMESTAMP] - Updated:
[CREATION_TIMESTAMP]-[UPDATE_TIMESTAMP] - Deleted:
[CREATION_TIMESTAMP]-[UPDATE_TIMESTAMP]-[DELETION_TIMESTAMP]
Each TTID segment contains:
- High-resolution timestamps encoded in base-36
- Progressive expansion to track lifecycle states
- Compact 11-character timestamps for efficiency
- Immutable deletion state (cannot be modified once deleted)
Installation
npm install ttidUsage
Basic ID Generation
import TTID from 'ttid';
// Generate a new TTID (creation only)
const newId = TTID.generate();
console.log(newId);
// Example output: "1A2B3C4D5E6"
// Verify if a string is a valid TTID
const isValid = TTID.isTTID(newId);
console.log(isValid); // Returns Date object if valid, null if invalidProgressive Updates
import TTID from 'ttid';
// Start with a new ID
let id = TTID.generate();
console.log(id); // "1A2B3C4D5E6"
// Update the ID (adds update timestamp)
id = TTID.generate(id);
console.log(id); // "1A2B3C4D5E6-F7G8H9I0J1"
// Update again (replaces update timestamp)
id = TTID.generate(id);
console.log(id); // "1A2B3C4D5E6-K2L3M4N5O6"
// Mark as deleted (adds deletion timestamp - final state)
id = TTID.generate(id, true);
console.log(id); // "1A2B3C4D5E6-K2L3M4N5O6-P7Q8R9S0T1"
// Attempting to modify a deleted ID throws an error
try {
TTID.generate(id); // Throws: "This identifier can no longer be modified"
} catch (error) {
console.error(error.message);
}Decoding Timestamps
import TTID from 'ttid';
// Create and update an ID
let id = TTID.generate();
setTimeout(() => {
id = TTID.generate(id);
setTimeout(() => {
id = TTID.generate(id, true); // Mark as deleted
// Decode all timestamps
const times = TTID.decodeTime(id);
console.log(times);
// Example output:
// {
// createdAt: 1651234567890,
// updatedAt: 1651234572345,
// deletedAt: 1651234578901
// }
// Convert to readable dates
console.log({
created: new Date(times.createdAt),
updated: times.updatedAt ? new Date(times.updatedAt) : null,
deleted: times.deletedAt ? new Date(times.deletedAt) : null
});
}, 2000);
}, 1000);Working with Different States
import TTID from 'ttid';
// Check ID states
function analyzeId(id: string) {
const validation = TTID.isTTID(id);
if (!validation) {
console.log('Invalid TTID');
return;
}
const segments = id.split('-');
const times = TTID.decodeTime(id);
console.log(`ID State: ${getIdState(segments.length)}`);
console.log(`Created: ${new Date(times.createdAt)}`);
if (times.updatedAt) {
console.log(`Updated: ${new Date(times.updatedAt)}`);
}
if (times.deletedAt) {
console.log(`Deleted: ${new Date(times.deletedAt)}`);
}
}
function getIdState(segmentCount: number) {
switch (segmentCount) {
case 1: return 'Created';
case 2: return 'Updated';
case 3: return 'Deleted';
default: return 'Unknown';
}
}
// Examples
const createdId = TTID.generate();
analyzeId(createdId); // ID State: Created
const updatedId = TTID.generate(createdId);
analyzeId(updatedId); // ID State: Updated
const deletedId = TTID.generate(updatedId, true);
analyzeId(deletedId); // ID State: DeletedError Handling
import TTID from 'ttid';
// Invalid ID format
try {
TTID.generate('invalid-id');
} catch (error) {
console.error(error.message); // "Invalid TTID!"
}
// Attempting to modify deleted ID
const id = TTID.generate();
const updated = TTID.generate(id);
const deleted = TTID.generate(updated, true);
try {
TTID.generate(deleted);
} catch (error) {
console.error(error.message); // "This identifier can no longer be modified"
}
// Invalid format for decoding
try {
TTID.decodeTime('not-a-ttid');
} catch (error) {
console.error(error.message); // "Invalid Format!"
}API Reference
TTID.generate(id?: string, del?: boolean)
Generates a new TTID or updates an existing one.
Parameters:
id(optional) - An existing TTID to updatedel(optional) - Set totrueto mark the ID as deleted
Returns: _ttid - A TTID string
Behavior:
- No parameters: Creates new ID
[TIMESTAMP] - Valid TTID provided: Updates to
[CREATED]-[NEW_TIMESTAMP] - Valid TTID +
del=true: Marks as deleted[CREATED]-[UPDATED]-[DELETED_TIMESTAMP]
Throws:
- Error if provided ID is invalid
- Error if attempting to modify a deleted ID (3 segments)
TTID.decodeTime(id: string)
Decodes timestamps from a TTID.
Parameters:
id- A TTID string
Returns: _timestamps object with:
createdAt- Creation timestamp in millisecondsupdatedAt(optional) - Update timestamp in millisecondsdeletedAt(optional) - Deletion timestamp in milliseconds
Throws: Error if the format is invalid
TTID.isTTID(id: string)
Validates a TTID and returns creation date if valid.
Parameters:
id- A string to validate
Returns:
Dateobject (creation date) if validnullif invalid
TTID.isUUID(id: string)
Checks if a string is a valid UUID.
Parameters:
id- A string to check
Returns: RegExpMatchArray | null - Match result or null
Format Specification
TTIDs follow a strict format:
- Base-36 encoding (0-9, A-Z)
- 11-character timestamps
- Hyphen-separated segments
- Progressive structure
Valid Patterns:
[A-Z0-9]{11}- Created only[A-Z0-9]{11}-[A-Z0-9]{1,11}- Created + Updated[A-Z0-9]{11}-[A-Z0-9]{1,11}-[A-Z0-9]{1,11}- Created + Updated + Deleted
Special Cases:
- Placeholder 'X' may appear in update position for certain states
- Deleted IDs cannot be modified further
Lifecycle States
| State | Format | Segments | Modifiable |
|-------|--------|----------|------------|
| Created | TIMESTAMP | 1 | ✅ |
| Updated | CREATED-UPDATED | 2 | ✅ |
| Deleted | CREATED-UPDATED-DELETED | 3 | ❌ |
Comparison with Other Systems
| Feature | TTID | UUID | ULID | |---------|------|------|------| | Progressive states | ✅ | ❌ | ❌ | | Soft delete tracking | ✅ | ❌ | ❌ | | Immutable final state | ✅ | ❌ | ❌ | | Compact encoding | ✅ | ❌ | ✅ | | Time-based | ✅ | ⚠️ | ✅ | | Fixed length | ❌ | ✅ | ✅ |
Use Cases
- Database Records: Track entity lifecycle (created → updated → soft deleted)
- Audit Systems: Maintain chronological history in the ID itself
- Document Management: Version control with embedded timestamps
- API Resources: RESTful endpoints with state-aware identifiers
- Event Sourcing: Compact event identifiers with temporal information
Performance Considerations
- Base-36 encoding provides compact representation
- Progressive format minimizes storage for simple states
- High-resolution timestamps ensure uniqueness in high-frequency scenarios
- Validation includes timestamp parsing for integrity checking
License
MIT
