RunPromise<T, J>
The RunPromise class provides an interface for executing SurrealDB functions and SurrealML models. It extends Promise, allowing you to await it directly or use configuration methods.
Returned by: SurrealQueryable.run()
Source: query/run.ts
Type Parameters
T - The return type of the functionJ - Boolean indicating if result is JSON (default: false)
Configuration Methods
.json()
Configure the query to return the result as a JSON string.
Method Syntax
runPromise.json()
Returns
RunPromise<T, true> - Promise returning JSON string
Example
const jsonResult = await db.run('fn::calculate', [10, 20]).json();
console.log(typeof jsonResult);
.stream()
Stream the function result.
Method Syntax
runPromise.stream()
Returns
AsyncIterableIterator<Frame<T, J>> - Async iterator
Complete Examples
Built-in Functions
import { Surreal } from 'surrealdb';
const db = new Surreal();
await db.connect('ws://localhost:8000');
const now = await db.run('time::now');
console.log('Current time:', now);
const timestamp = await db.run('time::unix');
console.log('Unix timestamp:', timestamp);
const unique = await db.run('array::distinct', [[1, 2, 2, 3, 3, 3]]);
console.log('Unique values:', unique);
const upper = await db.run('string::uppercase', ['hello world']);
console.log(upper);
const rounded = await db.run('math::round', [3.14159]);
console.log(rounded);
const hash = await db.run('crypto::md5', ['password123']);
console.log('Hash:', hash);
Custom Functions
await db.query(`
DEFINE FUNCTION fn::calculate_total($items: array) {
RETURN array::sum($items.map(|$item| $item.price * $item.quantity));
};
`).collect();
const items = [
{ price: 10, quantity: 2 },
{ price: 5, quantity: 3 }
];
const total = await db.run('fn::calculate_total', [items]);
console.log('Total:', total);
SurrealML Models
const prediction = await db.run(
'ml::predict_sentiment',
'1.0.0',
['This is a great product!']
);
console.log('Sentiment:', prediction);
With Type Safety
interface CalculationResult {
sum: number;
average: number;
count: number;
}
const result = await db.run<CalculationResult>(
'fn::calculate_stats',
[[10, 20, 30, 40, 50]]
);
console.log('Sum:', result.sum);
console.log('Average:', result.average);
console.log('Count:', result.count);
Complex Function Arguments
const result = await db.run('fn::process_order', [
new RecordId('users', 'john'),
new RecordId('products', 'widget'),
{
quantity: 5,
shipping_address: '123 Main St',
payment_method: 'credit_card'
}
]);
Parameterized Functions
await db.set('discount_rate', 0.1);
const total = await db.run('fn::calculate_price', [
100,
]);
Error Handling
try {
const result = await db.run('fn::risky_operation', [data]);
} catch (error) {
if (error instanceof ResponseError) {
console.error('Function failed:', error.message);
}
}
Batch Function Calls
const results = await db.query(`
RETURN fn::process(${data1});
RETURN fn::process(${data2});
RETURN fn::process(${data3});
`).collect();
console.log('Batch results:', results);
With Transaction
const txn = await db.beginTransaction();
try {
const result = await txn.run('fn::allocate_inventory', [
new RecordId('products', 'widget'),
10
]);
await txn.create(new Table('orders')).content({
product: result.product,
allocated: result.quantity
});
await txn.commit();
} catch (error) {
await txn.cancel();
}
Scheduled Functions
await db.query(`
DEFINE FUNCTION fn::cleanup_old_records() {
DELETE FROM logs WHERE created_at < time::now() - 30d;
};
`).collect();
await db.run('fn::cleanup_old_records');
Recursive Functions
await db.query(`
DEFINE FUNCTION fn::factorial($n: number) {
IF $n <= 1 THEN
RETURN 1
ELSE
RETURN $n * fn::factorial($n - 1)
END
};
`).collect();
const result = await db.run('fn::factorial', [5]);
console.log('5! =', result);
await db.query(`
DEFINE FUNCTION fn::format_user($user: record) {
RETURN {
full_name: string::concat($user.first_name, ' ', $user.last_name),
email: string::lowercase($user.email),
age: time::year(time::now()) - time::year($user.birth_date)
};
};
`).collect();
const user = await db.select(new RecordId('users', 'john'));
const formatted = await db.run('fn::format_user', [user]);
console.log(formatted);
ML Model Versions
const v1Result = await db.run('ml::classify_image', '1.0.0', [imageData]);
const v2Result = await db.run('ml::classify_image', '2.0.0', [imageData]);
console.log('v1 prediction:', v1Result);
console.log('v2 prediction:', v2Result);
Validation Functions
await db.query(`
DEFINE FUNCTION fn::validate_email($email: string) {
RETURN string::is::email($email);
};
`).collect();
const isValid = await db.run('fn::validate_email', ['user@example.com']);
if (isValid) {
}
Best Practices
1. Type Function Results
interface Stats {
count: number;
average: number;
}
const stats = await db.run<Stats>('fn::calculate_stats', [data]);
stats.count;
const stats = await db.run('fn::calculate_stats', [data]);
stats.count;
2. Handle Function Errors
try {
const result = await db.run('fn::risky_operation', [data]);
} catch (error) {
console.error('Function failed:', error);
}
await db.query(`
DEFINE FUNCTION fn::safe_operation($data: any) {
TRY {
RETURN fn::risky_operation($data);
} CATCH {
RETURN { error: true, message: 'Operation failed' };
}
};
`).collect();
3. Validate Function Names
Function names must follow the pattern: namespace::function_name
await db.run('fn::my_function', []);
await db.run('custom::calculate', []);
await db.run('ml::predict', '1.0.0', []);
await db.run('invalid name', []);
await db.run('fn:bad-name', []);
See Also