@rivium/sync-node
v0.1.0
Published
RiviumSync Node.js SDK - Server-side SDK for RiviumSync Realtime Database
Maintainers
Readme
@rivium/sync-node
Official Node.js SDK for RiviumSync Realtime Database. Designed for server-side applications with admin-level access.
Features
- Admin-level access - Bypasses security rules by default
- Full CRUD operations - Create, read, update, delete documents
- Query support - Filters, sorting, pagination
- Batch operations - Atomic writes across multiple documents
- Optional realtime - MQTT-based subscriptions when needed
- TypeScript - Full type definitions included
Installation
# npm
npm install @rivium/sync-node
# yarn
yarn add @rivium/sync-node
# pnpm
pnpm add @rivium/sync-nodeQuick Start
import { RiviumSyncAdmin } from '@rivium/sync-node';
// Initialize with your Project API Key and Server Secret
const riviumSync = new RiviumSyncAdmin({
apiKey: process.env.RIVIUM_SYNC_API_KEY, // nl_live_xxx or nl_test_xxx
serverSecret: process.env.RIVIUM_SYNC_SERVER_SECRET, // nl_srv_xxx - Required for server-side operations
});
// Get a database reference (database must be created via dashboard first)
const db = riviumSync.database('your-database-id');
// Get a collection reference
const users = db.collection('users');Note: Both
apiKeyandserverSecretare required for all server-side SDK operations. You can find these credentials in your AuthLeap Dashboard when you create a project. Database creation and deletion is managed via the dashboard, not via SDK.
CRUD Operations
Create a Document
// Add with auto-generated ID
const newUser = await users.add({
name: 'John Doe',
email: '[email protected]',
age: 28,
createdAt: new Date().toISOString(),
});
console.log('Created user with ID:', newUser.id);
// Set with specific ID
await users.doc('user-123').set({
name: 'Jane Doe',
email: '[email protected]',
});Read Documents
// Get a single document
const user = await users.get('user-123');
if (user) {
console.log('User name:', user.data.name);
}
// Check if document exists
const exists = await users.doc('user-123').exists();
// Get all documents
const allUsers = await users.getAll();
console.log('Total users:', allUsers.length);Update Documents
// Partial update (merge)
await users.doc('user-123').update({
age: 29,
updatedAt: new Date().toISOString(),
});
// Full replace
await users.doc('user-123').set({
name: 'John Updated',
email: '[email protected]',
age: 29,
});Delete Documents
await users.doc('user-123').delete();Querying
// Build queries with fluent API
const adults = await users
.where('age', '>=', 18)
.where('status', '==', 'active')
.orderBy('createdAt', 'desc')
.limit(20)
.get();
// Get first result only
const firstUser = await users
.where('email', '==', '[email protected]')
.query()
.getFirst();
// Count matching documents
const activeCount = await users
.where('status', '==', 'active')
.query()
.count();
// Pagination
const page1 = await users.orderBy('name').limit(10).get();
const page2 = await users.orderBy('name').limit(10).offset(10).get();Available Query Operators
| Operator | Description |
|----------|-------------|
| == | Equal |
| != | Not equal |
| < | Less than |
| <= | Less than or equal |
| > | Greater than |
| >= | Greater than or equal |
| in | Value in array |
| not-in | Value not in array |
| array-contains | Array contains value |
Batch Operations
Execute multiple writes atomically:
const batch = riviumSync.batch();
// Add operations to the batch
batch.set(users.doc('user1'), { name: 'User 1', status: 'active' });
batch.update(users.doc('user2'), { lastSeen: new Date().toISOString() });
batch.delete(users.doc('user3'));
// Commit all operations
await batch.commit();Realtime Updates (Optional)
Enable realtime subscriptions for server-side event processing:
const riviumSync = new RiviumSyncAdmin({
apiKey: process.env.RIVIUM_SYNC_API_KEY!,
serverSecret: process.env.RIVIUM_SYNC_SERVER_SECRET!,
enableRealtime: true, // Enable MQTT connection
});
// Listen to a single document
const unsubscribe = users.doc('user-123').onSnapshot((user) => {
if (user) {
console.log('User updated:', user.data);
} else {
console.log('User was deleted');
}
});
// Listen to a collection
const unsubscribeAll = users.onSnapshot((allUsers) => {
console.log('Users changed, count:', allUsers.length);
});
// Listen to query results
const unsubscribeQuery = users
.where('status', '==', 'online')
.onSnapshot((onlineUsers) => {
console.log('Online users:', onlineUsers.length);
});
// Stop listening when done
unsubscribe();
unsubscribeAll();
unsubscribeQuery();Configuration Options
const riviumSync = new RiviumSyncAdmin({
// Required
apiKey: 'nl_live_xxxxxxxxxxxxxxxxxxxxx', // Required - from AuthLeap Dashboard
serverSecret: 'nl_srv_xxxxxxxxxxxxxxxxxxxxx', // Required - from AuthLeap Dashboard
// Optional
enableRealtime: false, // Enable MQTT subscriptions
logLevel: RiviumSyncLogLevel.ERROR, // Logging level
timeout: 30000, // Request timeout in ms
});Credentials
| Credential | Format | Description |
|------------|--------|-------------|
| API Key | nl_live_xxx or nl_test_xxx | Used for client-side SDKs and server-side SDKs |
| Server Secret | nl_srv_xxx | Required for server-side operations. Never expose in client-side code. |
Both credentials are generated when you create a project in the AuthLeap Dashboard. Store them securely and never commit them to version control.
Log Levels
import { RiviumSyncLogLevel } from '@rivium/sync-node';
RiviumSyncLogLevel.NONE // No logs
RiviumSyncLogLevel.ERROR // Only errors
RiviumSyncLogLevel.WARNING // Errors and warnings
RiviumSyncLogLevel.INFO // General info
RiviumSyncLogLevel.DEBUG // Debug info
RiviumSyncLogLevel.VERBOSE // EverythingTypeScript Support
Full TypeScript support with generics:
interface User {
name: string;
email: string;
age: number;
status: 'active' | 'inactive';
}
const users = db.collection<User>('users');
// All operations are now typed
const newUser = await users.add({
name: 'John',
email: '[email protected]',
age: 28,
status: 'active',
});
// Type inference works
const user = await users.get('user-123');
if (user) {
console.log(user.data.name); // string
console.log(user.data.age); // number
}Error Handling
import { RiviumSyncError, RiviumSyncErrorCode } from '@rivium/sync-node';
try {
await users.get('nonexistent-id');
} catch (error) {
if (error instanceof RiviumSyncError) {
console.error('Error code:', error.code);
console.error('Message:', error.message);
console.error('Details:', error.details);
if (error.code === RiviumSyncErrorCode.DOCUMENT_NOT_FOUND) {
// Handle not found
}
}
}Use Cases
Backend API Server
// Express.js example
import express from 'express';
import { RiviumSyncAdmin } from '@rivium/sync-node';
const app = express();
const riviumSync = new RiviumSyncAdmin({
apiKey: process.env.RIVIUM_SYNC_API_KEY!,
serverSecret: process.env.RIVIUM_SYNC_SERVER_SECRET!,
});
const db = riviumSync.database('my-database');
app.get('/api/users', async (req, res) => {
const users = await db.collection('users').getAll();
res.json(users);
});
app.post('/api/users', async (req, res) => {
const user = await db.collection('users').add(req.body);
res.json(user);
});Serverless Functions
// AWS Lambda example
import { RiviumSyncAdmin } from '@rivium/sync-node';
const riviumSync = new RiviumSyncAdmin({
apiKey: process.env.RIVIUM_SYNC_API_KEY!,
serverSecret: process.env.RIVIUM_SYNC_SERVER_SECRET!,
});
export async function handler(event) {
const db = riviumSync.database('my-database');
const users = await db.collection('users')
.where('status', '==', 'active')
.get();
return {
statusCode: 200,
body: JSON.stringify(users),
};
}Data Migration Script
import { RiviumSyncAdmin } from '@rivium/sync-node';
const riviumSync = new RiviumSyncAdmin({
apiKey: process.env.RIVIUM_SYNC_API_KEY!,
serverSecret: process.env.RIVIUM_SYNC_SERVER_SECRET!,
});
const db = riviumSync.database('my-database');
async function migrate() {
const users = await db.collection('users').getAll();
const batch = riviumSync.batch();
for (const user of users) {
// Add migration logic
batch.update(db.collection('users').doc(user.id), {
migratedAt: new Date().toISOString(),
version: 2,
});
}
await batch.commit();
console.log('Migration complete!');
}
migrate();API Reference
RiviumSyncAdmin
| Method | Description |
|--------|-------------|
| database(id) | Get a database reference |
| batch() | Create a write batch |
| disconnect() | Disconnect from realtime |
| setLogLevel(level) | Change log level |
SyncDatabase
| Method | Description |
|--------|-------------|
| collection<T>(id) | Get a typed collection reference |
SyncCollection
| Method | Description |
|--------|-------------|
| doc(id) | Get a document reference |
| add(data) | Create document with auto ID |
| get(id) | Get a single document |
| getAll(options?) | Get all documents |
| where(field, op, value) | Start a query |
| orderBy(field, direction?) | Start a sorted query |
| limit(count) | Start a limited query |
| query() | Get query builder |
| onSnapshot(callback, options?) | Listen to changes |
SyncDocumentRef
| Method | Description |
|--------|-------------|
| get() | Get document data |
| exists() | Check if document exists |
| set(data) | Set document (overwrite) |
| update(data) | Update document (merge) |
| delete() | Delete document |
| onSnapshot(callback) | Listen to changes |
SyncQuery
| Method | Description |
|--------|-------------|
| where(field, op, value) | Add filter |
| orderBy(field, direction?) | Set ordering |
| limit(count) | Limit results |
| offset(count) | Skip results |
| startAfter(count) | Alias for offset |
| get() | Execute query |
| getFirst() | Get first result |
| count() | Count results |
| onSnapshot(callback) | Listen to query |
WriteBatch
| Method | Description |
|--------|-------------|
| set(docRef, data) | Add set operation |
| update(docRef, data) | Add update operation |
| delete(docRef) | Add delete operation |
| commit() | Execute all operations |
| size | Number of pending operations |
License
MIT
