roboto-js
v1.9.9
Published
JavaScript/TypeScript SDK for the Roboto platform - a unified client library for managing objects, files, users, and real-time data synchronization.
Readme
roboto-js
JavaScript/TypeScript SDK for the Roboto platform - a unified client library for managing objects, files, users, and real-time data synchronization.
Version: 1.9.5
Features
- Object Management: Create, read, update, and delete platform objects with a simple API
- File Handling: Upload and manage files with resumable uploads via tus protocol
- User Authentication: Login, registration, OAuth, and session management
- Real-time Sync: WebSocket-based live updates for collaborative applications
- Access Control: Fine-grained permissions with user, group, and organization-level sharing
- Storage Adapters: Flexible authentication storage (cookies, localStorage, custom)
- Metrics & Analytics: Built-in metrics API for tracking and analytics
- Dual Module Support: Works in both CommonJS and ES Module environments
- Browser & Node.js: Runs in browsers and Node.js server environments
Installation
npm install roboto-jsQuick Start
Basic Initialization
import Roboto from 'roboto-js';
const roboto = new Roboto({
host: 'your-api-host.com',
accessKey: 'your-access-key'
});Authentication
// Login
const user = await roboto.login({
email: '[email protected]',
password: 'password'
});
// Get current user
const currentUser = await roboto.loadCurrentUser();
// Logout
await roboto.logout();Working with Objects
// Create a new object
const site = await roboto.create('<@doc_website.site>', {
configs: {
label: 'My Website',
domain: 'example.com'
}
});
// Load an object
const loadedSite = await roboto.load('<@doc_website.site>', 'site-id-123');
// Update and save
site.set('configs.label', 'Updated Website');
await site.save();
// Query objects
const sites = await roboto.query('<@doc_website.site>', {
where: 'configs.status=active'
});File Uploads
// Create a file object
const file = await roboto.createFile({
filename: 'document.pdf',
mimetype: 'application/pdf'
});
// Upload with progress tracking
await file.upload(fileBlob, {
onProgress: (bytesUploaded, bytesTotal) => {
const percent = (bytesUploaded / bytesTotal) * 100;
console.log(`Upload progress: ${percent.toFixed(2)}%`);
}
});Configuration Options
const roboto = new Roboto({
host: 'api.example.com', // API host (required)
accessKey: 'your-access-key', // Access key (required)
authToken: 'token', // Optional: pre-set auth token
apiKey: 'key', // Optional: API key for service calls
useCookies: true, // Use cookies for auth (default: true)
cookieDomain: 'auto', // Cookie domain: 'auto', 'none', or explicit domain
localStorageAdaptor: customAdaptor, // Custom storage adapter
disableWebSocket: false, // Disable WebSocket connections
metricsHost: 'metrics.example.com' // Separate metrics host (optional)
});Core API Methods
Object Operations
create(type, data)- Create a new objectload(type, ids, options)- Load object(s) by IDquery(type, params)- Query objects with filterswrapAsRbtObjects(data)- Convert raw JSON to RbtObject instances
User Management
login(params)- Authenticate userloginWithOauth(params)- OAuth authenticationlogout()- End sessionregisterUser(params)- Create new user accountloadCurrentUser()- Get authenticated userconfirmUserEmail(params)- Verify email address
Organization Management
loadCurrentOrganization(forceReload)- Load user's current organizationswitchOrganization(orgId)- Switch to a different organizationgetCurrentOrganization()- Get cached current organizationcurrentOrganization- Getter for current organization
File Operations
createFile(data)- Create file objectloadFile(id)- Load file by IDloadFiles(ids)- Load multiple files
Task Execution
runTask(params, callbacks)- Execute background taskstopJob(params)- Cancel running jobpollTaskProgress(params)- Check task status
HTTP Methods
get(endpoint, params)- GET request with auto-wrappingpost(endpoint, data)- POST request with auto-wrapping
RbtObject Methods
RbtObject is the core class for working with platform data:
// Data access
object.get('path.to.property') // Get value
object.getData(['key1', 'key2']) // Get multiple values
object.set('path.to.property', value) // Set value
object.set('path', value, { merge: true }) // Merge objects
// Persistence
await object.save() // Save changes
await object.delete() // Delete object
await object.reload() // Refresh from server
// Metadata
object.id // Object ID
object.getType() // Object type
object.getRevision() // Revision number
object.hasUnsavedChanges() // Check for pending changes
// Real-time sync
object.enableRealtime() // Enable live updates
object.disableRealtime() // Disable live updates
object.on('change', callback) // Listen for changes
object.broadcastChange('path') // Broadcast to other clientsAccess Control & Sharing
Control who can access your objects:
// Make object public
await object.publishObject();
await object.unpublishObject();
// Check if published
if (object.isPublished()) {
console.log('Object is public');
}
// Grant access to users
await object.grantAccess({
userIds: ['user1', 'user2'],
write: false // read-only
});
// Grant access to groups
await object.grantAccess({
groupIds: ['grpAdmins'],
write: true // read and write
});
// Revoke access
await object.revokeAccess({
userIds: ['user1'],
groupIds: ['grpViewers']
});
// Get current permissions
const perms = object.getSharing();
console.log(perms.readGrants.users);
console.log(perms.writeGrants.userGroups);See SHARING_GUIDE.md for detailed examples and patterns.
Organization Management
Manage the current organization context for multi-tenant applications:
// Load current organization (automatic on login)
const org = await roboto.loadCurrentOrganization();
console.log('Current org:', org.get('name'));
// Access organization data
const orgName = org.get('name');
const taxId = org.get('profile.taxId');
// Access module-specific settings
const fiscalYearEnd = org.get('mod.accounting.fiscalYearEnd');
const defaultPipeline = org.get('mod.crm.defaultPipeline');
// Update organization data
org.set('name', 'Updated Company Name');
org.set('mod.accounting.baseCurrency', 'USD');
await org.save();
// Switch to a different organization
const newOrg = await roboto.switchOrganization('org-456');
console.log('Switched to:', newOrg.get('name'));
// Get cached organization (no API call)
const cached = roboto.getCurrentOrganization();
// or
const cached = roboto.currentOrganization;Organization on Login
Organizations are automatically loaded after successful login:
await roboto.login({
email: '[email protected]',
password: 'password'
});
// Organization is now available
const org = roboto.currentOrganization;
console.log('Logged in to:', org.get('name'));
// Disable automatic organization load
await roboto.login({
email: '[email protected]',
password: 'password',
loadOrganization: false // Skip org loading
});Server-Side Organization Context
// Express middleware with per-request organization
app.use((req, res, next) => {
req.roboto = new Roboto({
host: 'api.example.com',
accessKey: process.env.ROBOTO_ACCESS_KEY
}, req);
next();
});
// Use in routes
app.get('/api/accounts', async (req, res) => {
const org = await req.roboto.loadCurrentOrganization();
// Query automatically scoped to organization via IAC
const accounts = await req.roboto.query('<@accounting.account>', {});
res.json({
organization: org.get('name'),
accounts
});
});Multi-Tenant Data Scoping
Organization context enables automatic multi-tenant data scoping:
// All queries are automatically scoped to current organization
const org = await roboto.loadCurrentOrganization();
// These queries only return data the organization has access to
const accounts = await roboto.query('<@accounting.account>', {});
const invoices = await roboto.query('<@accounting.invoice>', {});
const contacts = await roboto.query('<@crm.contact>', {});
// Switch organizations and queries update automatically
await roboto.switchOrganization('different-org-id');
const newAccounts = await roboto.query('<@accounting.account>', {});
// Now returns accounts for the new organizationReal-time Collaboration
Enable live updates across clients:
// Enable real-time on an object
const doc = await roboto.load('<@doc.document>', 'doc-123');
doc.enableRealtime();
// Listen for changes
doc.on('change', (path, value) => {
console.log(`${path} changed to`, value);
});
// Broadcast changes to other clients
doc.set('content.text', 'Updated text');
doc.broadcastChange('content.text'); // Others receive this immediately
// Disable when done
doc.disableRealtime();Storage Adapters
Cookie Storage (Default for Browser)
import Roboto, { CookieStorageAdaptor } from 'roboto-js';
const roboto = new Roboto({
host: 'api.example.com',
accessKey: 'key',
useCookies: true, // Enabled by default
cookieDomain: 'auto' // Auto-detect root domain
});
// Custom cookie configuration
const cookieAdaptor = new CookieStorageAdaptor({
secure: true,
sameSite: 'Lax',
maxAge: 86400, // 24 hours
domain: '.example.com'
});
const roboto = new Roboto({
host: 'api.example.com',
accessKey: 'key',
localStorageAdaptor: cookieAdaptor
});Custom Storage Adapter
const customAdaptor = {
getItem: async (key) => {
// Return stored value
},
setItem: async (key, value) => {
// Store value
},
removeItem: async (key) => {
// Remove value
}
};
const roboto = new Roboto({
host: 'api.example.com',
accessKey: 'key',
localStorageAdaptor: customAdaptor
});Server-Side Usage (Node.js)
Use with Express middleware for per-request instances:
import Roboto from 'roboto-js';
// Middleware to attach roboto to each request
app.use((req, res, next) => {
// proxyReq allows per-request authentication
req.roboto = new Roboto({
host: 'api.example.com',
accessKey: process.env.ROBOTO_ACCESS_KEY
}, req); // Pass request object
next();
});
// Use in routes
app.get('/api/sites', async (req, res) => {
const sites = await req.roboto.query('<@doc_website.site>', {});
res.json(sites);
});Metrics API
Track events and analytics:
// Using default metrics endpoint
await roboto.metrics.logEvent({
event: 'user_action',
properties: {
action: 'button_click',
page: 'home'
}
});
// Custom metrics host
roboto.setMetricsHost('metrics.example.com');Environment-Specific Features
Browser
- Automatic WebSocket connection
- IndexedDB for local caching
- Cookie-based authentication by default
- Cross-subdomain cookie support
Node.js
- Per-request instances with
proxyReq - Custom header support for authentication
- No WebSocket auto-connection
Advanced Features
Auto-Wrapping Responses
The SDK automatically converts doctree objects to RbtObject instances:
// Raw API call returns plain objects
const response = await fetch('/api/custom-endpoint');
const data = await response.json();
// Wrap for RbtObject functionality
const objects = roboto.wrapAsRbtObjects(data.items);
// Now use RbtObject methods
objects[0].set('title', 'New Title');
await objects[0].save();Object Caching
Objects are cached automatically to prevent duplicate instances:
// Both calls return the same instance
const obj1 = await roboto.load('<@doc.item>', 'abc123');
const obj2 = await roboto.load('<@doc.item>', 'abc123');
console.log(obj1 === obj2); // trueError Handling
Set a custom error handler:
roboto.setErrorHandler((error, context) => {
console.error('API Error:', error.message);
console.error('Context:', context);
// Custom error reporting
errorReporter.report(error);
});Build & Development
# Install dependencies
npm install
# Build for production (strips console.log, keeps console.error)
npm run build
# Build CommonJS only
npm run build:cjs
# Build ES Modules only
npm run build:esm
# Update version
npm run update-version
# Clean install
npm run cleanSee BUILD_NOTES.md for build configuration details.
Module Formats
The package supports both module systems:
ES Modules (import)
import Roboto, { RbtObject, RbtFile } from 'roboto-js';CommonJS (require)
const Roboto = require('roboto-js');
const { RbtObject, RbtFile } = require('roboto-js');TypeScript Support
While this is a JavaScript library, it works seamlessly with TypeScript projects. Type definitions may be added in future versions.
Examples
See the examples directory for complete working examples:
- sharing-example.js - Access control patterns
Exports
import Roboto, {
RbtApi, // Low-level API client
RbtObject, // Object wrapper class
RbtFile, // File wrapper class
CookieStorageAdaptor // Cookie-based storage
} from 'roboto-js';Browser Compatibility
- Modern browsers with ES6+ support
- IndexedDB support for local caching
- WebSocket support for real-time features
- Cookie support for authentication
Node.js Compatibility
- Node.js 14+ recommended
- ES Modules or CommonJS
- No browser-specific APIs used in core functionality
License
ISC
Version History
Current version: 1.9.5
Version is automatically synced from package.json during build.
