npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

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-js

Quick 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 object
  • load(type, ids, options) - Load object(s) by ID
  • query(type, params) - Query objects with filters
  • wrapAsRbtObjects(data) - Convert raw JSON to RbtObject instances

User Management

  • login(params) - Authenticate user
  • loginWithOauth(params) - OAuth authentication
  • logout() - End session
  • registerUser(params) - Create new user account
  • loadCurrentUser() - Get authenticated user
  • confirmUserEmail(params) - Verify email address

Organization Management

  • loadCurrentOrganization(forceReload) - Load user's current organization
  • switchOrganization(orgId) - Switch to a different organization
  • getCurrentOrganization() - Get cached current organization
  • currentOrganization - Getter for current organization

File Operations

  • createFile(data) - Create file object
  • loadFile(id) - Load file by ID
  • loadFiles(ids) - Load multiple files

Task Execution

  • runTask(params, callbacks) - Execute background task
  • stopJob(params) - Cancel running job
  • pollTaskProgress(params) - Check task status

HTTP Methods

  • get(endpoint, params) - GET request with auto-wrapping
  • post(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 clients

Access 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 organization

Real-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);  // true

Error 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 clean

See 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:

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.