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

@object-ui/data-objectstack

v3.3.0

Published

ObjectStack Data Adapter for Object UI

Downloads

357

Readme

@object-ui/data-objectstack

Official ObjectStack data adapter for Object UI.

Overview

This package provides the ObjectStackAdapter class, which connects Object UI's universal DataSource interface with the @objectstack/client SDK.

This enables strictly typed, metadata-driven UI components to communicate seamlessly with ObjectStack backends (Steedos, Salesforce, etc.).

Installation

npm install @object-ui/data-objectstack @objectstack/client

Usage

Basic Setup

import { createObjectStackAdapter } from '@object-ui/data-objectstack';
import { SchemaRenderer } from '@object-ui/react';

// 1. Create the adapter
const dataSource = createObjectStackAdapter({
  baseUrl: 'https://api.example.com',
  token: 'your-api-token' // Optional if effectively handling auth elsewhere
});

// 2. Pass to the Renderer
function App() {
  return (
    <SchemaRenderer 
      schema={mySchema} 
      dataSource={dataSource} 
    />
  );
}

Advanced Configuration

const dataSource = createObjectStackAdapter({
  baseUrl: 'https://api.example.com',
  token: 'your-api-token',
  // Configure metadata cache
  cache: {
    maxSize: 100,      // Maximum number of cached schemas (default: 100)
    ttl: 5 * 60 * 1000 // Time to live in ms (default: 5 minutes)
  },
  // Configure auto-reconnect
  autoReconnect: true,           // Enable auto-reconnect (default: true)
  maxReconnectAttempts: 5,       // Max reconnection attempts (default: 3)
  reconnectDelay: 2000           // Initial delay between reconnects in ms (default: 1000)
});

Features

  • CRUD Operations: Implements find, findOne, create, update, delete.
  • Metadata Caching: Automatic LRU caching of schema metadata with TTL expiration.
  • Metadata Fetching: Implements getObjectSchema to power auto-generated forms and grids.
  • Query Translation: Converts Object UI's OData-like query parameters to ObjectStack's native query format.
  • Bulk Operations: Supports optimized batch create/update/delete with detailed error reporting.
  • Error Handling: Comprehensive error hierarchy with unique error codes and debugging details.
  • Connection Monitoring: Real-time connection state tracking with event listeners.
  • Auto-Reconnect: Automatic reconnection with exponential backoff on connection failures.
  • Batch Progress: Progress events for tracking bulk operation status.

Metadata Caching

The adapter includes built-in metadata caching to improve performance when fetching schemas:

// Get cache statistics
const stats = dataSource.getCacheStats();
console.log(`Cache hit rate: ${stats.hitRate * 100}%`);
console.log(`Cache size: ${stats.size}/${stats.maxSize}`);

// Manually invalidate cache entries
dataSource.invalidateCache('users'); // Invalidate specific schema
dataSource.invalidateCache();        // Invalidate all cached schemas

// Clear cache and statistics
dataSource.clearCache();

Cache Configuration

  • LRU Eviction: Automatically evicts least recently used entries when cache is full
  • TTL Expiration: Entries expire after the configured time-to-live from creation (default: 5 minutes)
    • Note: TTL is fixed from creation time, not sliding based on access
  • Memory Limits: Configurable maximum cache size (default: 100 entries)
  • Concurrent Access: Handles async operations safely. Note that concurrent requests for the same uncached key may result in multiple fetcher calls.

Connection State Monitoring

The adapter provides real-time connection state monitoring with automatic reconnection:

// Monitor connection state changes
const unsubscribe = dataSource.onConnectionStateChange((event) => {
  console.log('Connection state:', event.state);
  console.log('Timestamp:', new Date(event.timestamp));
  
  if (event.error) {
    console.error('Connection error:', event.error);
  }
});

// Check current connection state
console.log(dataSource.getConnectionState()); // 'disconnected' | 'connecting' | 'connected' | 'reconnecting' | 'error'

// Check if connected
if (dataSource.isConnected()) {
  console.log('Adapter is connected');
}

// Unsubscribe from events when done
unsubscribe();

Connection States

  • disconnected - Not connected to server
  • connecting - Attempting initial connection
  • connected - Successfully connected
  • reconnecting - Attempting to reconnect after failure
  • error - Connection failed (check event.error for details)

Auto-Reconnect

The adapter automatically attempts to reconnect on connection failures:

  • Exponential Backoff: Delay increases with each attempt (delay × 2^(attempts-1))
  • Configurable Attempts: Set maxReconnectAttempts (default: 3)
  • Configurable Delay: Set reconnectDelay for initial delay (default: 1000ms)
  • Automatic: Enabled by default, disable with autoReconnect: false

Batch Operation Progress

Track progress of bulk operations in real-time:

// Monitor batch operation progress
const unsubscribe = dataSource.onBatchProgress((event) => {
  console.log(`${event.operation}: ${event.percentage.toFixed(1)}%`);
  console.log(`Completed: ${event.completed}/${event.total}`);
  console.log(`Failed: ${event.failed}`);
});

// Perform bulk operation
const users = await dataSource.bulk('users', 'create', largeDataset);

// Unsubscribe when done
unsubscribe();

Progress Event Properties

  • operation - Operation type ('create' | 'update' | 'delete')
  • total - Total number of items
  • completed - Number of successfully completed items
  • failed - Number of failed items
  • percentage - Completion percentage (0-100)

Error Handling

The adapter provides a comprehensive error hierarchy for better error handling:

Error Types

import {
  ObjectStackError,        // Base error class
  MetadataNotFoundError,   // Schema/metadata not found (404)
  BulkOperationError,      // Bulk operation failures with partial results
  ConnectionError,         // Network/connection errors (503/504)
  AuthenticationError,     // Authentication failures (401/403)
  ValidationError,         // Data validation errors (400)
} from '@object-ui/data-objectstack';

Error Handling Example

try {
  const schema = await dataSource.getObjectSchema('users');
} catch (error) {
  if (error instanceof MetadataNotFoundError) {
    console.error(`Schema not found: ${error.details.objectName}`);
  } else if (error instanceof ConnectionError) {
    console.error(`Connection failed to: ${error.url}`);
  } else if (error instanceof AuthenticationError) {
    console.error('Authentication required');
  }
  
  // All errors have consistent structure
  console.error({
    code: error.code,
    message: error.message,
    statusCode: error.statusCode,
    details: error.details
  });
}

Bulk Operation Errors

Bulk operations provide detailed error reporting with partial success information:

try {
  await dataSource.bulk('users', 'update', records);
} catch (error) {
  if (error instanceof BulkOperationError) {
    const summary = error.getSummary();
    console.log(`${summary.successful} succeeded, ${summary.failed} failed`);
    console.log(`Failure rate: ${summary.failureRate * 100}%`);
    
    // Inspect individual failures
    summary.errors.forEach(({ index, error }) => {
      console.error(`Record ${index} failed:`, error);
    });
  }
}

Error Codes

All errors include unique error codes for programmatic handling:

  • METADATA_NOT_FOUND - Schema/metadata not found
  • BULK_OPERATION_ERROR - Bulk operation failure
  • CONNECTION_ERROR - Connection/network error
  • AUTHENTICATION_ERROR - Authentication failure
  • VALIDATION_ERROR - Data validation error
  • UNSUPPORTED_OPERATION - Unsupported operation
  • NOT_FOUND - Resource not found
  • UNKNOWN_ERROR - Unknown error

Batch Operations

The adapter supports optimized batch operations with automatic fallback:

// Batch create
const newUsers = await dataSource.bulk('users', 'create', [
  { name: 'Alice', email: '[email protected]' },
  { name: 'Bob', email: '[email protected]' },
]);

// Batch update (uses updateMany if available, falls back to individual updates)
const updated = await dataSource.bulk('users', 'update', [
  { id: '1', name: 'Alice Smith' },
  { id: '2', name: 'Bob Jones' },
]);

// Batch delete
await dataSource.bulk('users', 'delete', [
  { id: '1' },
  { id: '2' },
]);

Performance Optimizations

  • Automatically uses createMany, updateMany, deleteMany when available
  • Falls back to individual operations with detailed error tracking
  • Provides partial success reporting for resilient error handling
  • Atomic operations where supported by the backend

API Reference

ObjectStackAdapter

Constructor

new ObjectStackAdapter(config: {
  baseUrl: string;
  token?: string;
  fetch?: (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
  cache?: {
    maxSize?: number;
    ttl?: number;
  };
  autoReconnect?: boolean;
  maxReconnectAttempts?: number;
  reconnectDelay?: number;
})

Methods

  • connect() - Establish connection to ObjectStack server
  • find(resource, params?) - Query multiple records
  • findOne(resource, id, params?) - Get a single record by ID
  • create(resource, data) - Create a new record
  • update(resource, id, data) - Update an existing record
  • delete(resource, id) - Delete a record
  • bulk(resource, operation, data) - Batch operations (create/update/delete)
  • getObjectSchema(objectName) - Get schema metadata (cached)
  • getCacheStats() - Get cache statistics
  • invalidateCache(key?) - Invalidate cache entries
  • clearCache() - Clear all cache entries
  • getClient() - Access underlying ObjectStack client
  • getConnectionState() - Get current connection state
  • isConnected() - Check if adapter is connected
  • onConnectionStateChange(listener) - Subscribe to connection state changes (returns unsubscribe function)
  • onBatchProgress(listener) - Subscribe to batch operation progress (returns unsubscribe function)

Best Practices

  1. Enable Caching: Use default cache settings for optimal performance
  2. Handle Errors: Use typed error handling for better user experience
  3. Batch Operations: Use bulk methods for large datasets
  4. Monitor Cache: Check cache hit rates in production
  5. Invalidate Wisely: Clear cache after schema changes
  6. Connection Monitoring: Subscribe to connection state changes for better UX
  7. Auto-Reconnect: Use default auto-reconnect settings for resilient applications
  8. Batch Progress: Monitor progress for long-running bulk operations

Troubleshooting

Common Issues

Schema Not Found

// Error: MetadataNotFoundError
// Solution: Verify object name and ensure schema exists on server
const schema = await dataSource.getObjectSchema('correct_object_name');

Connection Errors

// Error: ConnectionError
// Solution: Check baseUrl and network connectivity
const dataSource = createObjectStackAdapter({
  baseUrl: 'https://correct-url.example.com',
  token: 'valid-token'
});

Cache Issues

// Clear cache if stale data is being returned
dataSource.clearCache();

// Or invalidate specific entries
dataSource.invalidateCache('users');

License

MIT