npm package: @superatomai/sdk-web
Description: SuperAtom Web SDK - TypeScript SDK for browser-based WebSocket communication
Latest version: 0.0.2-mds

# @superatomai/sdk-web

SuperAtom Web SDK - TypeScript SDK for browser-based WebSocket communication with the SuperAtom platform.

## Features

- 🔌 WebSocket client with automatic reconnection and exponential backoff
- 🔒 Type-safe message validation using Zod v4
- 🎯 Request/response pattern with timeout support
- 📦 Bundle management with chunked transfer
- 🧩 Component registration and communication system
- 🔐 Authentication (login and token verification)
- 👥 User management (CRUD operations)
- 📊 Dashboard management (CRUD operations)
- 📈 Report management (CRUD operations)
- 🤖 AI component suggestions with text streaming support
- 💾 Data collection queries
- ⚡ Actions API for runtime operations
- 📝 UI logging support

## Installation

```bash
pnpm add @superatomai/sdk-web
```

## Quick Start

```typescript
import { SuperatomClient, setup } from '@superatomai/sdk-web';

// 1. Create and connect client
const client = new SuperatomClient({
  userId: 'your-user-id',
  projectId: 'your-project-id',
  type: 'runtime', // Connection type (default: 'runtime')
  debug: true, // Enable debug logging
});

await client.connect();

// 2. Setup components (optional - for component rendering)
setup({
  MyComponent: MyReactComponent,
  AnotherComponent: AnotherReactComponent,
  mount: (Component, container, props) => {
    const root = createRoot(container);
    root.render(createElement(Component, props));
    return { unmount: () => root.unmount() };
  }
});

// 3. Authenticate (optional)
const loginResponse = await client.sendAuthLoginRequest(
  loginDataBase64, // Base64 encoded login data
  10000 // timeout in ms
);

// 4. Get AI component suggestions
const result = await client.sendUserPromptSuggestionsRequest(
  'show me a calendar component',
  5 // limit
);
```

## API Reference

### SuperatomClient

Main WebSocket client for communication.

#### Configuration

```typescript
const client = new SuperatomClient({
  userId: string,                    // Required: User ID
  projectId: string,                 // Required: Project ID
  type?: string,                     // Default: 'runtime'
  baseUrl?: string,                  // Default: 'wss://ws.superatom.ai/websocket'
  maxReconnectAttempts?: number,     // Default: Infinity
  initialReconnectDelay?: number,    // Default: 1000ms
  maxReconnectDelay?: number,        // Default: 30000ms
  defaultTimeout?: number,           // Default: 30000ms
  debug?: boolean,                   // Default: false
});
```

#### Core Methods

```typescript
// Connection management
await client.connect();                              // Returns Promise<void>
client.disconnect();
client.isConnected();                                // Returns boolean
await client.reconnectWithConfig(partialConfig);     // Reconnect with updated config

// Messaging
client.send(message);                                // Send message without waiting for response
await client.sendWithResponse(message, timeout);     // Send and wait for response
await client.ask(message, { timeout });              // Alias for sendWithResponse

// Event handlers
client.onMessage((message) => { ... });              // Returns unsubscribe function
client.onConnect(() => { ... });                     // Returns unsubscribe function
client.onDisconnect(() => { ... });                  // Returns unsubscribe function
client.onError((error) => { ... });                  // Returns unsubscribe function
```

### Service Methods

#### Authentication

```typescript
// Login with credentials
const loginResponse = await client.sendAuthLoginRequest(
  loginDataBase64,  // Base64 encoded: username + SHA-1 hashed password
  timeout          // Optional timeout in ms
);

// Verify authentication token
const verifyResponse = await client.sendAuthVerifyRequest(
  token,    // Base64 encoded auth token
  timeout   // Optional timeout in ms
);
```

#### User Management

```typescript
// Create a new user
const result = await client.createUser(
  username,
  password,
  email?,      // Optional: User email
  fullname?,   // Optional: User full name
  role?,       // Optional: User role
  timeout?
);
// Returns: { success, username?, email?, fullname?, role?, message?, error? }

// Update an existing user
const result = await client.updateUser(
  username,
  {
    password?: string,   // Optional: New password
    email?: string,      // Optional: New email
    fullname?: string,   // Optional: New full name
    role?: string,       // Optional: New role
  },
  timeout?
);
// Returns: { success, username?, email?, fullname?, role?, message?, error? }

// Delete a user
const result = await client.deleteUser(username, timeout);
// Returns: { success, username?, email?, fullname?, role?, message?, error? }

// Get all users
const result = await client.getAllUsers(timeout);
// Returns: { success, users, count, error?, message? }
// User object: { username, email?, fullname?, role?, wsIds }

// Get a specific user
const result = await client.getUser(username, timeout);
// Returns: { success, user, error?, message? }
// User object: { username, email?, fullname?, role?, wsIds }
```

#### Dashboard Management

```typescript
// Create a new dashboard
const result = await client.createDashboard(
  dashboardId,
  dashboardConfig,  // DSLRendererProps
  timeout
);

// Update an existing dashboard
const result = await client.updateDashboard(
  dashboardId,
  dashboardConfig,
  timeout
);

// Delete a dashboard
const result = await client.deleteDashboard(dashboardId, timeout);

// Get all dashboards
const result = await client.getAllDashboards(timeout);
// Returns: { success, dashboards, count, error?, message? }

// Get a specific dashboard
const result = await client.getDashboard(dashboardId, timeout);
// Returns: { success, dashboardId, dashboard, error?, message? }
```

#### Report Management

```typescript
// Create a new report
const result = await client.createReport(
  reportId,
  reportConfig,  // ReportDSLRendererProps
  timeout
);

// Update an existing report
const result = await client.updateReport(
  reportId,
  reportConfig,
  timeout
);

// Delete a report
const result = await client.deleteReport(reportId, timeout);

// Get all reports
const result = await client.getAllReports(timeout);
// Returns: { success, reports, count, error?, message? }

// Get a specific report
const result = await client.getReport(reportId, timeout);
// Returns: { success, reportId, report, error?, message? }
```

#### User Prompts & AI Suggestions

```typescript
// Send a user prompt request (component mode - default)
const response = await client.sendUserPromptRequest(
  prompt,
  threadId,
  uiBlockId,
  'component',  // responseMode: 'component' (default) or 'text'
  undefined,    // onStream callback (only used for text mode)
  timeout
);

// Send a user prompt request with text streaming
const response = await client.sendUserPromptRequest(
  prompt,
  threadId,
  uiBlockId,
  'text',       // responseMode: 'text' for streaming
  (chunk) => {  // onStream callback receives text chunks
    console.log('Stream chunk:', chunk);
  },
  timeout
);

// Get AI component suggestions
const result = await client.sendUserPromptSuggestionsRequest(
  'show me a form to collect user data',
  5,       // limit (default: 5)
  timeout  // optional timeout
);
```

#### Bundle & Data

```typescript
// Request bundle with progress tracking
const bundle = await client.requestBundle({
  timeout: 60000,
  onProgress: (progress) => {
    console.log(`Download progress: ${progress}%`);
  }
});

// Query data collections
const result = await client.requestData({
  collection: 'users',
  operation: 'getMany',
  params: { limit: 10 },
  timeout: 10000
});
// Returns: { data?, error? }
```

#### Actions API

```typescript
// Get available actions for the current context
const result = await client.getActions({
  SA_RUNTIME: {
    threadId: 'thread_123',
    uiBlockId: 'block_456'
  },
  timeout: 10000
});
// Returns: { success, data?, error? }
```

#### Component Management

```typescript
// Send component list to server
await client.sendComponents([
  {
    id: 'comp_1',
    name: 'MyComponent',
    type: 'custom',
    description: 'A custom component',
    props: { /* ... */ }
  },
  // ... more components
]);
```

### Component Setup

Register your components with SuperAtom for dynamic rendering.

```typescript
import { setup } from '@superatomai/sdk-web';
import { createRoot } from 'react-dom/client';
import { createElement } from 'react';

setup({
  // Your components
  DemoCard: DemoCard,
  Calendar: Calendar,
  Form: ComplexForm,

  // Mount function (required)
  mount: (Component, container, props) => {
    const root = createRoot(container);
    root.render(createElement(Component, props));
    return { unmount: () => root.unmount() };
  }
});
```

## Message Types

The SDK supports the following message types (all validated with Zod schemas):

**Authentication**
- `AUTH_LOGIN_REQ` / `AUTH_LOGIN_RES` - User login
- `AUTH_VERIFY_REQ` / `AUTH_VERIFY_RES` - Token verification

**User Prompts & AI**
- `USER_PROMPT_REQ` / `USER_PROMPT_RES` - User prompt processing
- `USER_PROMPT_STREAM` - Real-time text streaming from AI responses
- `USER_PROMPT_SUGGESTIONS_REQ` / `USER_PROMPT_SUGGESTIONS_RES` - Component suggestions

**Bundle & Data**
- `BUNDLE_REQ` / `BUNDLE_CHUNK` - Bundle transfer with chunking
- `DATA_REQ` / `DATA_RES` - Data collection queries

**Management Operations**
- `USERS` / `USERS_RES` - User CRUD operations
- `DASHBOARDS` / `DASHBOARDS_RES` - Dashboard CRUD operations
- `REPORTS` / `REPORTS_RES` - Report CRUD operations

**Actions & Components**
- `ACTIONS` / `ACTIONS_RES` - Runtime actions API
- `COMPONENT_LIST_RES` - Send component list to server

**Logging**
- `UI_LOGS` - UI logging messages

All message types are fully typed and validated using Zod v4 schemas.

### USERS Schema

The USERS message type supports comprehensive user management with the following structure:

**Request Payload** (`USERS`):
```typescript
{
  operation: 'create' | 'update' | 'delete' | 'getAll' | 'getOne',
  data?: {
    username?: string,        // Required for all operations except getAll
    email?: string,           // Optional: User email (validated)
    password?: string,        // Required for create, optional for update
    fullname?: string,        // Optional: User's full name
    role?: string,            // Optional: User's role
  }
}
```

**Response Payload** (`USERS_RES`):
```typescript
{
  success: boolean,
  error?: string,
  data?: {
    username?: string,
    email?: string,
    fullname?: string,
    role?: string,
    message?: string,
    // For getAll operation
    users?: Array<{
      username: string,
      email?: string,
      fullname?: string,
      role?: string,
      wsIds: string[]
    }>,
    count?: number,
    // For getOne operation
    user?: {
      username: string,
      email?: string,
      fullname?: string,
      role?: string,
      wsIds: string[]
    }
  }
}
```

**User Object Structure**:
```typescript
interface User {
  username: string;          // Required: Unique username
  email?: string;            // Optional: Validated email address
  fullname?: string;         // Optional: User's full name
  role?: string;             // Optional: User role (e.g., 'admin', 'editor', 'viewer')
  wsIds: string[];           // WebSocket connection IDs (in-memory only)
}
```

## Type Safety

All messages are validated using Zod v4 schemas. The SDK exports comprehensive type definitions and schemas:

```typescript
import {
  MessageSchema,
  DataRequestMessageSchema,
  AuthLoginRequestMessageSchema,
  UserPromptSuggestionsRequestMessageSchema,
  // ... and many more
} from '@superatomai/sdk-web';

// Validate any message
const validMessage = MessageSchema.parse(incomingData);

// Validate specific message types
const dataRequest = DataRequestMessageSchema.parse(requestData);

// TypeScript types are automatically inferred
import type {
  Message,
  DataRequestMessage,
  AuthLoginResponseMessage,
  Component,
  DSLRendererProps,
  ReportDSLRendererProps,
} from '@superatomai/sdk-web';
```

## Examples

### Complete React Integration

```typescript
import { SuperatomClient, setup } from '@superatomai/sdk-web';
import { createRoot } from 'react-dom/client';
import { createElement } from 'react';
import MyComponent from './components/MyComponent';

// Initialize client
const client = new SuperatomClient({
  userId: 'user_123',
  projectId: 'project_456',
  type: 'runtime',
  debug: true,
});

// Setup components
setup({
  MyComponent,
  mount: (Component, container, props) => {
    const root = createRoot(container);
    root.render(createElement(Component, props));
    return { unmount: () => root.unmount() };
  }
});

// Connect and authenticate
await client.connect();

// Listen for messages
client.onMessage((message) => {
  console.log('Received:', message);
});

// Get component suggestions
async function handleUserQuery(query: string) {
  const result = await client.sendUserPromptSuggestionsRequest(query, 5);

  if (result?.payload?.data?.suggestions) {
    console.log('Suggestions:', result.payload.data.suggestions);
  }
}
```

### User Management Example

```typescript
import { SuperatomClient } from '@superatomai/sdk-web';

const client = new SuperatomClient({
  userId: 'admin_123',
  projectId: 'project_456',
});

await client.connect();

// Create a new user with all fields
const createResult = await client.createUser(
  'newuser',
  'password123',
  'user@example.com',     // email
  'John Doe',             // fullname
  'editor'                // role
);
if (createResult.success) {
  console.log('User created:', createResult.username);
  console.log('Email:', createResult.email);
  console.log('Full name:', createResult.fullname);
  console.log('Role:', createResult.role);
}

// Get all users
const usersResult = await client.getAllUsers();
if (usersResult.success && usersResult.users) {
  console.log(`Found ${usersResult.count} users`);
  usersResult.users.forEach(user => {
    console.log(`- ${user.username} (${user.email || 'no email'})`);
    console.log(`  Full name: ${user.fullname || 'N/A'}`);
    console.log(`  Role: ${user.role || 'N/A'}`);
    console.log(`  Connections: ${user.wsIds.length}`);
  });
}

// Update a user - change multiple fields
await client.updateUser('newuser', {
  password: 'newpassword456',
  email: 'newemail@example.com',
  fullname: 'Jane Doe',
  role: 'admin'
});

// Update a user - change only specific fields
await client.updateUser('newuser', {
  role: 'viewer'  // Only update role
});

// Delete a user
await client.deleteUser('newuser');
```

### Dashboard Management Example

```typescript
import { SuperatomClient } from '@superatomai/sdk-web';
import type { DSLRendererProps } from '@superatomai/sdk-web';

const client = new SuperatomClient({
  userId: 'admin_123',
  projectId: 'project_456',
});

await client.connect();

// Create a dashboard
const dashboardConfig: DSLRendererProps = {
  // Your dashboard configuration
};

const result = await client.createDashboard(
  'dashboard_001',
  dashboardConfig
);

if (result.success) {
  console.log('Dashboard created:', result.dashboardId);
}

// Get all dashboards
const dashboards = await client.getAllDashboards();
if (dashboards.success && dashboards.dashboards) {
  console.log(`Total dashboards: ${dashboards.count}`);
}

// Get specific dashboard
const dashboard = await client.getDashboard('dashboard_001');
if (dashboard.success && dashboard.dashboard) {
  console.log('Dashboard config:', dashboard.dashboard);
}
```

### Data Query Example

```typescript
import { SuperatomClient } from '@superatomai/sdk-web';

const client = new SuperatomClient({
  userId: 'user_123',
  projectId: 'project_456',
});

await client.connect();

// Query data from a collection
const result = await client.requestData({
  collection: 'products',
  operation: 'getMany',
  params: {
    filter: { category: 'electronics' },
    limit: 20,
    offset: 0
  },
  timeout: 10000
});

if (!result.error && result.data) {
  console.log('Products:', result.data);
} else {
  console.error('Error:', result.error);
}
```

### Text Streaming Example

```typescript
import { SuperatomClient } from '@superatomai/sdk-web';

const client = new SuperatomClient({
  userId: 'user_123',
  projectId: 'project_456',
});

await client.connect();

// Use text streaming for real-time AI responses
let streamedText = '';

const response = await client.sendUserPromptRequest(
  'Explain how photosynthesis works',
  'thread_123',
  'block_456',
  'text',  // Enable text streaming mode
  (chunk) => {
    // Receive text chunks in real-time
    streamedText += chunk;
    console.log('Received chunk:', chunk);
    // Update UI with streaming text
    updateUIWithText(streamedText);
  },
  30000
);

console.log('Streaming complete. Final response:', response);
```

### Actions API Example

```typescript
import { SuperatomClient } from '@superatomai/sdk-web';

const client = new SuperatomClient({
  userId: 'user_123',
  projectId: 'project_456',
});

await client.connect();

// Get available actions for the current runtime context
const result = await client.getActions({
  SA_RUNTIME: {
    threadId: 'thread_123',
    uiBlockId: 'block_456'
  },
  timeout: 10000
});

if (result.success && result.data) {
  console.log('Available actions:', result.data);
} else {
  console.error('Error:', result.error);
}

// Send component list to server
await client.sendComponents([
  {
    id: 'my_component_1',
    name: 'DataTable',
    type: 'table',
    description: 'Display data in table format',
    props: {
      columns: ['name', 'email', 'status'],
      data: []
    }
  }
]);
```

## Advanced Usage

### Direct Service Access

All service functions can be imported and used directly for advanced use cases:

```typescript
import { SuperatomClient, services } from '@superatomai/sdk-web';

const client = new SuperatomClient({ /* ... */ });

// Use service functions directly
const result = await services.requestData(client, {
  collection: 'users',
  operation: 'getMany',
  params: {},
  timeout: 10000
});
```

### Event Unsubscription

All event handlers return an unsubscribe function:

```typescript
const unsubscribe = client.onMessage((message) => {
  console.log('Message:', message);
});

// Later, when you want to stop listening
unsubscribe();
```

### Reconnection with Updated Config

You can reconnect with updated configuration without creating a new client:

```typescript
await client.reconnectWithConfig({
  userId: 'new_user_id',
  debug: true
});
```

## License

MIT

## Support

For issues and questions, please contact the SuperAtom team or refer to the SuperAtom platform documentation.