title: @ddb-lib/core API description: Core utilities and pattern helpers for DynamoDB
@ddb-lib/core API reference¶
Core utilities for implementing DynamoDB patterns and best practices. This package provides pure utility functions with no external dependencies.
Installation¶
Overview¶
The @ddb-lib/core package provides:
- PatternHelpers - Functions for common DynamoDB patterns
- Multi-Attribute Key Helpers - Functions for creating complex composite keys
- Expression Builders - Type-safe builders for DynamoDB expressions
- Type Guards - Runtime type validation utilities
- Validators - Key and configuration validation
Quick start¶
import { PatternHelpers } from '@ddb-lib/core'
// Create entity keys
const userKey = PatternHelpers.entityKey('USER', '123')
// Returns: 'USER#123'
// Create composite keys
const orderKey = PatternHelpers.compositeKey(['ORDER', userId, orderId])
// Returns: 'ORDER#123#456'
// Create time-series keys
const tsKey = PatternHelpers.timeSeriesKey(new Date(), 'day')
// Returns: '2024-12-03'
// Create distributed keys for hot partition prevention
const shardedKey = PatternHelpers.distributedKey('ACTIVE_USERS', 10)
// Returns: 'ACTIVE_USERS#SHARD_7' (random shard 0-9)
PatternHelpers class¶
Static utility class for implementing DynamoDB patterns.
Compositekey()¶
Create a composite key from multiple parts.
Parameters: - parts - Array of key parts to combine - separator - Separator character (default: '#')
Returns: Composite key string
Example:
const key = PatternHelpers.compositeKey(['USER', '123', 'ORDER', '456'])
// Returns: 'USER#123#ORDER#456'
// Custom separator
const key = PatternHelpers.compositeKey(['A', 'B', 'C'], '|')
// Returns: 'A|B|C'
Throws: Error if parts array is empty or if any part contains the separator
Parsecompositekey()¶
Parse a composite key into its component parts.
Parameters: - key - Composite key string - separator - Separator character (default: '#')
Returns: Array of key parts
Example:
const parts = PatternHelpers.parseCompositeKey('USER#123#ORDER#456')
// Returns: ['USER', '123', 'ORDER', '456']
Entitykey()¶
Create an entity key with type prefix for single-table design.
Parameters: - entityType - Type of entity (e.g., 'USER', 'ORDER', 'PRODUCT') - id - Entity identifier
Returns: Entity key string
Example:
const userKey = PatternHelpers.entityKey('USER', '123')
// Returns: 'USER#123'
const orderKey = PatternHelpers.entityKey('ORDER', 'abc-def')
// Returns: 'ORDER#abc-def'
Use Cases: - Single-table design with multiple entity types - Type-safe entity identification - Human-readable keys for debugging
Parseentitykey()¶
Parse an entity key to extract type and ID.
Parameters: - key - Entity key string
Returns: Object with entityType and id properties
Example:
const parsed = PatternHelpers.parseEntityKey('USER#123')
// Returns: { entityType: 'USER', id: '123' }
const parsed = PatternHelpers.parseEntityKey('ORDER#abc-def')
// Returns: { entityType: 'ORDER', id: 'abc-def' }
Timeserieskey()¶
Create a time-series key from a date with specified granularity.
Parameters: - timestamp - Date object - granularity - Time granularity ('hour', 'day', or 'month')
Returns: Time-series key string
Example:
const date = new Date('2024-12-02T15:30:00')
PatternHelpers.timeSeriesKey(date, 'hour')
// Returns: '2024-12-02-15'
PatternHelpers.timeSeriesKey(date, 'day')
// Returns: '2024-12-02'
PatternHelpers.timeSeriesKey(date, 'month')
// Returns: '2024-12'
Use Cases: - Time-series data storage - Log aggregation by time period - Metrics collection
Ttltimestamp()¶
Convert a Date to a TTL timestamp (Unix epoch in seconds).
Parameters: - expiresAt - Date when the item should expire
Returns: Unix timestamp in seconds
Example:
const expiryDate = new Date('2024-12-31T23:59:59')
const ttl = PatternHelpers.ttlTimestamp(expiryDate)
// Returns: 1735689599
// Use in DynamoDB item
await table.put({
pk: 'SESSION#123',
sk: 'DATA',
ttl: PatternHelpers.ttlTimestamp(new Date(Date.now() + 3600000)) // 1 hour
})
Adjacencykeys()¶
Create adjacency list keys for relationship patterns.
Parameters: - sourceId - Source entity ID - targetId - Target entity ID
Returns: Object with pk and sk for the relationship
Example:
const keys = PatternHelpers.adjacencyKeys('USER#123', 'ORDER#456')
// Returns: { pk: 'USER#123', sk: 'ORDER#456' }
// Store relationship
await table.put({
...keys,
relationshipType: 'OWNS',
createdAt: Date.now()
})
Use Cases: - Graph-like relationships - Many-to-many relationships - Social networks (followers, friends)
Hierarchicalkey()¶
Create a hierarchical key from a path array.
Parameters: - path - Array of path segments
Returns: Hierarchical key string
Example:
const key = PatternHelpers.hierarchicalKey(['root', 'folder1', 'subfolder', 'item'])
// Returns: 'root/folder1/subfolder/item'
// Query all items in a folder
const results = await table.query({
keyCondition: {
pk: 'FILES',
sk: { beginsWith: 'root/folder1/' }
}
})
Parsehierarchicalkey()¶
Parse a hierarchical key into its path components.
Parameters: - key - Hierarchical key string
Returns: Array of path segments
Example:
const path = PatternHelpers.parseHierarchicalKey('root/folder1/subfolder/item')
// Returns: ['root', 'folder1', 'subfolder', 'item']
Distributedkey()¶
Create a distributed key with shard suffix for write sharding.
Parameters: - baseKey - Base partition key - shardCount - Number of shards to distribute across
Returns: Distributed key with random shard suffix
Example:
const key = PatternHelpers.distributedKey('POPULAR_ITEM', 10)
// Returns: 'POPULAR_ITEM#SHARD_7' (random shard 0-9)
// Write to random shard
await table.put({
pk: PatternHelpers.distributedKey('ACTIVE_USERS', 10),
sk: `USER#${userId}`,
...userData
})
// Query all shards
const allUsers = []
for (let i = 0; i < 10; i++) {
const result = await table.query({
keyCondition: { pk: `ACTIVE_USERS#SHARD_${i}` }
})
allUsers.push(...result.items)
}
Use Cases: - Preventing hot partitions - High-traffic write scenarios - Popular items or trending content
Getshardnumber()¶
Extract the shard number from a distributed key.
Parameters: - key - Distributed key string
Returns: Shard number, or null if not a distributed key
Example:
PatternHelpers.getShardNumber('POPULAR_ITEM#SHARD_7')
// Returns: 7
PatternHelpers.getShardNumber('REGULAR_KEY')
// Returns: null
Versionattribute()¶
Get the standard attribute name for version tracking.
Returns: Standard version attribute name ('version')
Example:
Incrementversion()¶
Increment a version number for optimistic locking.
Parameters: - currentVersion - Current version number
Returns: Incremented version number
Example:
const newVersion = PatternHelpers.incrementVersion(1)
// Returns: 2
// Use with optimistic locking
await table.update({
pk: 'USER#123',
sk: 'PROFILE',
updates: {
name: 'New Name',
version: PatternHelpers.incrementVersion(currentVersion)
},
condition: {
version: { eq: currentVersion }
}
})
Sparseindexvalue()¶
Create a sparse index value conditionally.
Parameters: - condition - Boolean condition to check - value - Value to return if condition is true
Returns: Value if condition is true, undefined otherwise
Example:
await table.put({
pk: 'USER#123',
sk: 'PROFILE',
email: 'user@example.com',
emailVerified: true,
// Only appears in GSI if email is verified
gsi1pk: PatternHelpers.sparseIndexValue(emailVerified, 'VERIFIED#USER')
})
// Query only verified users
const verified = await table.query({
indexName: 'GSI1',
keyCondition: { gsi1pk: 'VERIFIED#USER' }
})
Use Cases: - Sparse GSIs for filtered queries - Conditional index inclusion - Status-based filtering
Gsikey()¶
Create a GSI key for GSI overloading pattern.
Parameters: - indexName - Name of the GSI (for documentation) - entityType - Type of entity - value - Value for the key
Returns: GSI key string
Example:
// Multiple entity types in same GSI
await table.put({
pk: 'USER#123',
sk: 'PROFILE',
gsi1pk: PatternHelpers.gsiKey('GSI1', 'USER', 'active'),
gsi1sk: 'USER#123'
})
await table.put({
pk: 'ORDER#456',
sk: 'METADATA',
gsi1pk: PatternHelpers.gsiKey('GSI1', 'ORDER', 'pending'),
gsi1sk: 'ORDER#456'
})
Multi-attribute key helpers¶
Functions for creating complex composite keys with multiple attributes.
Multiattributekey()¶
Create a multi-attribute key value array.
function multiAttributeKey(
...values: Array<string | number | Uint8Array>
): Array<string | number | Uint8Array>
Parameters: - values - Variable number of values for the key
Returns: Array of key values
Example:
import { multiAttributeKey } from '@ddb-lib/core'
const key = multiAttributeKey('TENANT-123', 'CUSTOMER-456', 'DEPT-A')
// Returns: ['TENANT-123', 'CUSTOMER-456', 'DEPT-A']
Multitenantkey()¶
Create a multi-tenant partition key.
function multiTenantKey(
tenantId: string,
customerId: string,
departmentId?: string
): Array<string>
Parameters: - tenantId - Tenant identifier - customerId - Customer identifier - departmentId - Optional department identifier
Returns: Array of key values
Example:
import { multiTenantKey } from '@ddb-lib/core'
// Two-level key
const key = multiTenantKey('TENANT-123', 'CUSTOMER-456')
// Returns: ['TENANT-123', 'CUSTOMER-456']
// Three-level key with department
const key = multiTenantKey('TENANT-123', 'CUSTOMER-456', 'DEPT-A')
// Returns: ['TENANT-123', 'CUSTOMER-456', 'DEPT-A']
Hierarchicalmultikey()¶
Create a hierarchical multi-attribute key.
function hierarchicalMultiKey(
level1: string,
level2?: string,
level3?: string,
level4?: string
): Array<string>
Parameters: - level1 - First level of hierarchy (required) - level2 - Second level (optional) - level3 - Third level (optional) - level4 - Fourth level (optional)
Returns: Array of key values
Example:
import { hierarchicalMultiKey } from '@ddb-lib/core'
// Full hierarchy
const key = hierarchicalMultiKey('USA', 'CA', 'San Francisco', 'Downtown')
// Returns: ['USA', 'CA', 'San Francisco', 'Downtown']
// Partial hierarchy
const key = hierarchicalMultiKey('USA', 'CA')
// Returns: ['USA', 'CA']
Timeseriesmultikey()¶
Create a time-series multi-attribute key.
function timeSeriesMultiKey(
category: string,
timestamp: Date | number,
subcategory?: string
): Array<string | number>
Parameters: - category - Primary category - timestamp - Unix timestamp or Date object - subcategory - Optional subcategory
Returns: Array of key values
Example:
import { timeSeriesMultiKey } from '@ddb-lib/core'
const key = timeSeriesMultiKey('ERROR', new Date('2024-12-02'))
// Returns: ['ERROR', 1733097600000]
// With subcategory
const key = timeSeriesMultiKey('ERROR', 1733097600000, 'DATABASE')
// Returns: ['ERROR', 1733097600000, 'DATABASE']
Locationmultikey()¶
Create a location-based multi-attribute key.
function locationMultiKey(
country: string,
state?: string,
city?: string,
district?: string
): Array<string>
Parameters: - country - Country code or name - state - State or province (optional) - city - City name (optional) - district - District (optional)
Returns: Array of location values
Example:
import { locationMultiKey } from '@ddb-lib/core'
const key = locationMultiKey('USA', 'CA', 'San Francisco', 'SOMA')
// Returns: ['USA', 'CA', 'San Francisco', 'SOMA']
Productcategorymultikey()¶
Create a product categorization multi-attribute key.
function productCategoryMultiKey(
category: string,
subcategory?: string,
brand?: string,
productLine?: string
): Array<string>
Parameters: - category - Top-level category - subcategory - Subcategory (optional) - brand - Brand name (optional) - productLine - Product line (optional)
Returns: Array of categorization values
Example:
import { productCategoryMultiKey } from '@ddb-lib/core'
const key = productCategoryMultiKey('Electronics', 'Laptops', 'Apple', 'MacBook Pro')
// Returns: ['Electronics', 'Laptops', 'Apple', 'MacBook Pro']
Statusprioritymultikey()¶
Create a status and priority multi-attribute key.
function statusPriorityMultiKey(
status: string,
priority: number | string,
assignee?: string
): Array<string | number>
Parameters: - status - Status value - priority - Priority level - assignee - Optional assignee (optional)
Returns: Array of status/priority values
Example:
import { statusPriorityMultiKey } from '@ddb-lib/core'
const key = statusPriorityMultiKey('PENDING', 1)
// Returns: ['PENDING', 1]
// With assignee
const key = statusPriorityMultiKey('ACTIVE', 2, 'USER-123')
// Returns: ['ACTIVE', 2, 'USER-123']
Versionmultikey()¶
Create a version-based multi-attribute key.
function versionMultiKey(
major: number,
minor?: number,
patch?: number,
build?: string | number
): Array<number | string>
Parameters: - major - Major version number - minor - Minor version (optional) - patch - Patch version (optional) - build - Build number (optional)
Returns: Array of version values
Example:
import { versionMultiKey } from '@ddb-lib/core'
const key = versionMultiKey(2, 1, 5)
// Returns: [2, 1, 5]
// With build
const key = versionMultiKey(2, 1, 5, 'beta-3')
// Returns: [2, 1, 5, 'beta-3']