Documentation Index Fetch the complete documentation index at: https://hyrex.io/docs/llms.txt
Use this file to discover all available pages before exploring further.
Hyrex provides a distributed key-value store for sharing state between tasks and workflows.
Basic Usage
The HyrexKV class provides static methods for key-value operations:
import { HyrexKV } from '@hyrex/hyrex' ;
// Set a value
await HyrexKV . set ( 'user-123' , 'John Doe' );
// Get a value
const userName = await HyrexKV . get ( 'user-123' );
console . log ( userName ); // 'John Doe'
Value Size Limits
The TypeScript SDK enforces a 1MB size limit for values:
// This will work
const smallData = JSON . stringify ({ items: [ 1 , 2 , 3 ] });
await HyrexKV . set ( 'small-data' , smallData );
// This will throw an error if > 1MB
const largeData = 'x' . repeat ( 1024 * 1024 + 1 ); // 1MB + 1 byte
try {
await HyrexKV . set ( 'large-data' , largeData );
} catch ( error ) {
// Error: Value size exceeds maximum allowed size of 1048576 bytes
}
Working with JSON Data
Store complex objects by serializing to JSON:
interface UserData {
id : string ;
name : string ;
preferences : Record < string , any >;
}
// Store object
const userData : UserData = {
id: '123' ,
name: 'Alice' ,
preferences: { theme: 'dark' , notifications: true }
};
await HyrexKV . set ( 'user-data' , JSON . stringify ( userData ));
// Retrieve and parse
const storedData = await HyrexKV . get ( 'user-data' );
const parsed = JSON . parse ( storedData ) as UserData ;
console . log ( parsed . name ); // 'Alice'
Use Cases
Task Communication
Share data between parent and child tasks:
const parentTask = hy . task ({
name: 'parentTask' ,
func : async () => {
const ctx = getHyrexContext ();
// Store data for child tasks
await HyrexKV . set ( `task- ${ ctx . taskId } -config` , JSON . stringify ({
batchSize: 100 ,
retryCount: 3
}));
// Launch child tasks
await childTask . send ({ parentId: ctx . taskId });
return { status: 'launched' };
}
});
const childTask = hy . task ({
name: 'childTask' ,
func : async ({ parentId } : { parentId : string }) => {
// Retrieve parent's configuration
const configStr = await HyrexKV . get ( `task- ${ parentId } -config` );
const config = JSON . parse ( configStr );
console . log ( `Processing with batch size: ${ config . batchSize } ` );
return { processed: true };
}
});
Workflow State
Share state between workflow tasks:
const dataWorkflow = hy . workflow ({
name: 'dataWorkflow' ,
body : ( workflowBuilder ) => {
workflowBuilder
. start ( fetchDataTask )
. next ( processDataTask )
. next ( saveResultsTask );
return workflowBuilder ;
},
config: {}
});
const fetchDataTask = hy . task ({
name: 'fetchData' ,
func : async () => {
const ctx = getHyrexContext ();
const data = await fetchFromAPI ();
// Store for next task in workflow
await HyrexKV . set (
`workflow- ${ ctx . workflowRunId } -data` ,
JSON . stringify ( data )
);
return { fetched: true };
}
});
const processDataTask = hy . task ({
name: 'processData' ,
func : async () => {
const ctx = getHyrexContext ();
// Retrieve data from previous task
const dataStr = await HyrexKV . get (
`workflow- ${ ctx . workflowRunId } -data`
);
const data = JSON . parse ( dataStr );
const processed = transformData ( data );
// Store for final task
await HyrexKV . set (
`workflow- ${ ctx . workflowRunId } -result` ,
JSON . stringify ( processed )
);
return { processed: true };
}
});
Distributed Locks
Implement simple distributed locks:
const lockTask = hy . task ({
name: 'lockTask' ,
func : async ({ resourceId } : { resourceId : string }) => {
const lockKey = `lock- ${ resourceId } ` ;
const lockValue = ` ${ getHyrexContext (). taskId } - ${ Date . now () } ` ;
try {
// Try to acquire lock
const existing = await HyrexKV . get ( lockKey ). catch (() => null );
if ( existing ) {
throw new Error ( 'Resource is locked' );
}
// Set lock
await HyrexKV . set ( lockKey , lockValue );
// Do work with exclusive access
await processExclusiveResource ( resourceId );
// Note: No delete method - use TTL or workflow cleanup
} catch ( error ) {
console . error ( 'Failed to acquire lock:' , error );
throw error ;
}
return { completed: true };
}
});
Caching
Cache expensive computation results:
const computeTask = hy . task ({
name: 'computeTask' ,
func : async ({ input } : { input : string }) => {
const cacheKey = `cache-compute- ${ input } ` ;
// Check cache
try {
const cached = await HyrexKV . get ( cacheKey );
if ( cached ) {
console . log ( 'Cache hit!' );
return JSON . parse ( cached );
}
} catch ( error ) {
// Cache miss, continue
}
// Expensive computation
console . log ( 'Cache miss, computing...' );
const result = await expensiveComputation ( input );
// Cache result
await HyrexKV . set ( cacheKey , JSON . stringify ( result ));
return result ;
}
});
Best Practices
Use Namespaced Keys
// Good - clear namespace and purpose
const key = `workflow- ${ workflowId } -step- ${ stepName } ` ;
const key = `cache-api- ${ endpoint } - ${ params } ` ;
const key = `user- ${ userId } -preferences` ;
// Avoid - ambiguous keys
const key = 'data' ;
const key = '123' ;
Handle Missing Keys
// Get with error handling
const getValue = async ( key : string ) : Promise < string | null > => {
try {
return await HyrexKV . get ( key );
} catch ( error ) {
// Key doesn't exist
return null ;
}
};
Clean Up Workflow Data
// Store with workflow-specific keys
const workflowKey = `workflow- ${ ctx . workflowRunId } -temp` ;
await HyrexKV . set ( workflowKey , data );
// Consider cleanup in final task
// Note: TypeScript SDK doesn't have delete method
Validate Data Size
const storeData = async ( key : string , data : any ) => {
const serialized = JSON . stringify ( data );
// Check size before storing (1MB limit)
const sizeInBytes = new TextEncoder (). encode ( serialized ). length ;
if ( sizeInBytes > 1024 * 1024 ) {
throw new Error ( `Data too large: ${ sizeInBytes } bytes` );
}
await HyrexKV . set ( key , serialized );
};
Limitations
No Delete Method : Keys cannot be explicitly deleted in the TypeScript SDK
1MB Size Limit : Values are limited to 1MB (1,048,576 bytes)
String Values Only : All values must be strings (serialize objects to JSON)
No TTL Support : Keys don’t expire automatically
Next Steps
Workflows Share data in workflows
Tasks Pass data between tasks
Cron Store state for scheduled tasks