context.storage
The context.storage object provides persistent storage for your mim. It supports key-value storage, tagged items, vector embeddings, pagination, transactions, and file operations.
Each mim has its own isolated storage database. Data stored by one mim is not accessible to other mims.
Quick Reference
| Category | Methods |
|---|---|
| Basic | getItem, setItem, removeItem |
| Tagged | setItemWithTag, removeItemsByTag, eachItemByTag |
| Embeddings | setEmbeddingWithTag, getEmbedding, removeEmbedding, removeEmbeddingsByTag, similaritySearch |
| Iteration | eachItem |
| Pagination | getJsonItemsPaginated |
| Transactions | lockExecute |
| Files | saveFile, deleteFile |
Basic Storage
getItem()
Retrieves a value from storage by key.
context.storage.getItem(key) → string | null
| Parameter | Type | Description |
|---|---|---|
key | string | The key to lookup |
Returns: The value as a string, or null if not found.
app.get('/user/:id', (request, response) => {
var user = context.storage.getItem('user:' + request.params.id);
if (user) {
response.end(user);
} else {
response.statusCode = 404;
response.end('Not found');
}
});
setItem()
Stores a value with the specified key.
context.storage.setItem(key, value)
| Parameter | Type | Description |
|---|---|---|
key | string | The key to store under |
value | string | The value to store |
app.post('/user', (request, response) => {
var user = JSON.parse(request.body);
context.storage.setItem('user:' + user.id, JSON.stringify(user));
response.end('User saved');
});
removeItem()
Removes a value from storage by key.
context.storage.removeItem(key)
| Parameter | Type | Description |
|---|---|---|
key | string | The key to remove |
app.delete('/user/:id', (request, response) => {
context.storage.removeItem('user:' + request.params.id);
response.end('User deleted');
});
Tagged Storage
Tags allow you to categorize items and perform bulk operations.
setItemWithTag()
Stores a value with an associated tag.
context.storage.setItemWithTag(key, value, tag)
| Parameter | Type | Description |
|---|---|---|
key | string | The key to store under |
value | string | The value to store |
tag | string | The tag to associate |
app.post('/user', (request, response) => {
var user = JSON.parse(request.body);
context.storage.setItemWithTag(
'user:' + user.id,
JSON.stringify(user),
'users'
);
response.end('User saved');
});
removeItemsByTag()
Removes all items with a specific tag.
context.storage.removeItemsByTag(tag)
| Parameter | Type | Description |
|---|---|---|
tag | string | The tag identifying items to remove |
app.delete('/users/all', (request, response) => {
context.storage.removeItemsByTag('users');
response.end('All users deleted');
});
eachItemByTag()
Iterates through all items with a specific tag.
context.storage.eachItemByTag(tag, callback)
| Parameter | Type | Description |
|---|---|---|
tag | string | The tag to filter by |
callback | function | Called for each item: (key, value) => boolean |
The callback receives key and value as arguments. Return true to continue iteration, false to stop.
app.get('/users', (request, response) => {
var users = [];
context.storage.eachItemByTag('users', function(key, value) {
users.push(JSON.parse(value));
return true; // continue iteration
});
response.end(JSON.stringify(users));
});
Embedding (Vector) Operations
Store and search vector embeddings for semantic similarity.
setEmbeddingWithTag()
Stores a vector embedding with an associated tag.
context.storage.setEmbeddingWithTag(key, embedding, tag)
| Parameter | Type | Description |
|---|---|---|
key | string | The key to store under |
embedding | number[] | The vector embedding as array of numbers |
tag | string | The tag to associate |
app.post('/document', (request, response) => {
var body = JSON.parse(request.body);
context.storage.setEmbeddingWithTag(
'doc:' + body.id,
body.embedding,
'documents'
);
response.end('Embedding stored');
});
getEmbedding()
Retrieves a vector embedding from storage.
context.storage.getEmbedding(key) → number[] | null
| Parameter | Type | Description |
|---|---|---|
key | string | The key of the embedding |
Returns: The embedding vector as array, or null if not found.
app.get('/document/:id/embedding', (request, response) => {
var embedding = context.storage.getEmbedding('doc:' + request.params.id);
if (embedding) {
response.end(JSON.stringify({ embedding: embedding }));
} else {
response.statusCode = 404;
response.end('Not found');
}
});
removeEmbedding()
Removes an embedding from storage.
context.storage.removeEmbedding(key)
| Parameter | Type | Description |
|---|---|---|
key | string | The key of the embedding to remove |
app.delete('/document/:id/embedding', (request, response) => {
context.storage.removeEmbedding('doc:' + request.params.id);
response.end('Embedding removed');
});
removeEmbeddingsByTag()
Removes all embeddings with a specific tag.
context.storage.removeEmbeddingsByTag(tag)
| Parameter | Type | Description |
|---|---|---|
tag | string | The tag identifying embeddings to remove |
app.delete('/documents/embeddings', (request, response) => {
context.storage.removeEmbeddingsByTag('documents');
response.end('All document embeddings removed');
});
similaritySearch()
Performs vector similarity search to find embeddings most similar to a query vector.
context.storage.similaritySearch(queryEmbedding, topN, tag, callback)
| Parameter | Type | Description |
|---|---|---|
queryEmbedding | number[] | The query vector |
topN | number | Maximum number of results |
tag | string | Tag to filter embeddings by |
callback | function | Called for each result: (key, similarity) => void |
The callback receives key and similarity (0 to 1, where 1 is most similar).
app.post('/search', (request, response) => {
var body = JSON.parse(request.body);
var results = [];
context.storage.similaritySearch(
body.queryEmbedding,
10,
'documents',
function(key, similarity) {
results.push({ key: key, similarity: similarity });
}
);
response.end(JSON.stringify(results));
});
Iteration
eachItem()
Iterates through all items in storage.
context.storage.eachItem(callback)
| Parameter | Type | Description |
|---|---|---|
callback | function | Called for each item: (key, value) => boolean |
Return true to continue, false to stop.
app.get('/dump', (request, response) => {
var items = [];
context.storage.eachItem(function(key, value) {
items.push({ key: key, value: value });
return true;
});
response.end(JSON.stringify(items));
});
Pagination & Querying
getJsonItemsPaginated()
Retrieves items with pagination, filtering, sorting, and grouping. Values must be valid JSON strings to use JSON path features.
context.storage.getJsonItemsPaginated(offset, limit, callback, options)
| Parameter | Type | Description |
|---|---|---|
offset | number | Number of records to skip (>= 0) |
limit | number | Number of records to return (>= 1) |
callback | function | Called with results: (items, totalCount) => void |
options | object | Query options (optional) |
Options
| Option | Type | Description |
|---|---|---|
tag | string | Filter by specific tag |
order | number | Simple ordering: positive for ASC, negative for DESC |
orderBy | array | Advanced ordering by JSON paths |
filters | array | Array of filter conditions |
groupBy | array | Array of JSON paths to group by |
orderBy Format
orderBy: [
{ jsonPath: '$.fieldName', order: 1 }, // ASC
{ jsonPath: '$.otherField', order: -1 } // DESC
]
filters Format
filters: [
{
jsonPath: '$.status',
comparisonOperator: '=', // =, !=, >, <, >=, <=, LIKE, IS NULL, IS NOT NULL
value: 'active'
}
]
Example
app.get('/users', (request, response) => {
var page = parseInt(request.query.page) || 0;
var pageSize = parseInt(request.query.pageSize) || 10;
var offset = page * pageSize;
context.storage.getJsonItemsPaginated(
offset,
pageSize,
function(items, totalCount) {
response.end(JSON.stringify({
data: JSON.parse(items),
pagination: {
page: page,
pageSize: pageSize,
totalCount: totalCount,
totalPages: Math.ceil(totalCount / pageSize)
}
}));
},
{
tag: 'users',
orderBy: [{ jsonPath: '$.createdAt', order: -1 }],
filters: [
{ jsonPath: '$.active', comparisonOperator: '=', value: 'true' }
]
}
);
});
Transactions
lockExecute()
Executes a callback with exclusive database access for atomic operations.
context.storage.lockExecute(callback)
| Parameter | Type | Description |
|---|---|---|
callback | function | Function to execute with locked access |
All storage operations inside the callback are executed atomically.
app.post('/transfer', (request, response) => {
var body = JSON.parse(request.body);
context.storage.lockExecute(function() {
var fromBalance = parseFloat(context.storage.getItem(body.from) || '0');
var toBalance = parseFloat(context.storage.getItem(body.to) || '0');
if (fromBalance >= body.amount) {
context.storage.setItem(body.from, String(fromBalance - body.amount));
context.storage.setItem(body.to, String(toBalance + body.amount));
response.end(JSON.stringify({ success: true }));
} else {
response.end(JSON.stringify({
success: false,
error: 'Insufficient funds'
}));
}
});
});
File Operations
saveFile()
Saves a file to the mim's working folder.
context.storage.saveFile(fileName, base64Data)
| Parameter | Type | Description |
|---|---|---|
fileName | string | Name of the file to save |
base64Data | string | File content as base64-encoded string |
app.post('/upload', (request, response) => {
var body = JSON.parse(request.body);
context.storage.saveFile(body.fileName, body.data);
response.end('File saved');
});
deleteFile()
Deletes a file from the mim's working folder.
context.storage.deleteFile(fileName)
| Parameter | Type | Description |
|---|---|---|
fileName | string | Name of the file to delete |
app.delete('/file/:name', (request, response) => {
context.storage.deleteFile(request.params.name);
response.end('File deleted');
});
Best Practices
Use Key Prefixes
Organize keys with prefixes to avoid collisions:
// Good
context.storage.setItem('user:123', userData);
context.storage.setItem('session:abc', sessionData);
context.storage.setItem('config:theme', 'dark');
// Avoid
context.storage.setItem('123', userData); // Ambiguous
Use Tags for Collections
Use tags to group related items:
// Store with tag
context.storage.setItemWithTag('user:123', userData, 'users');
context.storage.setItemWithTag('user:456', userData, 'users');
// Query all users
context.storage.eachItemByTag('users', function(key, value) {
// Process each user
return true;
});
// Delete all users
context.storage.removeItemsByTag('users');
Use Transactions for Consistency
Wrap related operations in lockExecute to ensure atomicity:
context.storage.lockExecute(function() {
var counter = parseInt(context.storage.getItem('counter') || '0');
context.storage.setItem('counter', String(counter + 1));
context.storage.setItem('lastUpdated', new Date().toISOString());
});
Related
- context.http: HTTP client API
- context.info: Node metadata and environment
- request: Incoming request object
- response: Response methods