@superatomai/sdk-web 0.0.15 → 0.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +755 -755
- package/dist/index.cjs +21 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -2
- package/dist/index.d.ts +14 -2
- package/dist/index.js +21 -11
- package/dist/index.js.map +1 -1
- package/package.json +41 -43
package/README.md
CHANGED
|
@@ -1,755 +1,755 @@
|
|
|
1
|
-
# @superatomai/sdk-web
|
|
2
|
-
|
|
3
|
-
SuperAtom Web SDK - TypeScript SDK for browser-based WebSocket communication with the SuperAtom platform.
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- 🔌 WebSocket client with automatic reconnection and exponential backoff
|
|
8
|
-
- 🔒 Type-safe message validation using Zod v4
|
|
9
|
-
- 🎯 Request/response pattern with timeout support
|
|
10
|
-
- 📦 Bundle management with chunked transfer
|
|
11
|
-
- 🧩 Component registration and communication system
|
|
12
|
-
- 🔐 Authentication (login and token verification)
|
|
13
|
-
- 👥 User management (CRUD operations)
|
|
14
|
-
- 📊 Dashboard management (CRUD operations)
|
|
15
|
-
- 📈 Report management (CRUD operations)
|
|
16
|
-
- 🤖 AI component suggestions with text streaming support
|
|
17
|
-
- 💾 Data collection queries
|
|
18
|
-
- ⚡ Actions API for runtime operations
|
|
19
|
-
- 📝 UI logging support
|
|
20
|
-
|
|
21
|
-
## Installation
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
pnpm add @superatomai/sdk-web
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
## Quick Start
|
|
28
|
-
|
|
29
|
-
```typescript
|
|
30
|
-
import { SuperatomClient, setup } from '@superatomai/sdk-web';
|
|
31
|
-
|
|
32
|
-
// 1. Create and connect client
|
|
33
|
-
const client = new SuperatomClient({
|
|
34
|
-
userId: 'your-user-id',
|
|
35
|
-
projectId: 'your-project-id',
|
|
36
|
-
type: 'runtime', // Connection type (default: 'runtime')
|
|
37
|
-
debug: true, // Enable debug logging
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
await client.connect();
|
|
41
|
-
|
|
42
|
-
// 2. Setup components (optional - for component rendering)
|
|
43
|
-
setup({
|
|
44
|
-
MyComponent: MyReactComponent,
|
|
45
|
-
AnotherComponent: AnotherReactComponent,
|
|
46
|
-
mount: (Component, container, props) => {
|
|
47
|
-
const root = createRoot(container);
|
|
48
|
-
root.render(createElement(Component, props));
|
|
49
|
-
return { unmount: () => root.unmount() };
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
// 3. Authenticate (optional)
|
|
54
|
-
const loginResponse = await client.sendAuthLoginRequest(
|
|
55
|
-
loginDataBase64, // Base64 encoded login data
|
|
56
|
-
10000 // timeout in ms
|
|
57
|
-
);
|
|
58
|
-
|
|
59
|
-
// 4. Get AI component suggestions
|
|
60
|
-
const result = await client.sendUserPromptSuggestionsRequest(
|
|
61
|
-
'show me a calendar component',
|
|
62
|
-
5 // limit
|
|
63
|
-
);
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
## API Reference
|
|
67
|
-
|
|
68
|
-
### SuperatomClient
|
|
69
|
-
|
|
70
|
-
Main WebSocket client for communication.
|
|
71
|
-
|
|
72
|
-
#### Configuration
|
|
73
|
-
|
|
74
|
-
```typescript
|
|
75
|
-
const client = new SuperatomClient({
|
|
76
|
-
userId: string, // Required: User ID
|
|
77
|
-
projectId: string, // Required: Project ID
|
|
78
|
-
type?: string, // Default: 'runtime'
|
|
79
|
-
baseUrl?: string, // Default: 'wss://ws.superatom.ai/websocket'
|
|
80
|
-
maxReconnectAttempts?: number, // Default: Infinity
|
|
81
|
-
initialReconnectDelay?: number, // Default: 1000ms
|
|
82
|
-
maxReconnectDelay?: number, // Default: 30000ms
|
|
83
|
-
defaultTimeout?: number, // Default: 30000ms
|
|
84
|
-
debug?: boolean, // Default: false
|
|
85
|
-
});
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
#### Core Methods
|
|
89
|
-
|
|
90
|
-
```typescript
|
|
91
|
-
// Connection management
|
|
92
|
-
await client.connect(); // Returns Promise<void>
|
|
93
|
-
client.disconnect();
|
|
94
|
-
client.isConnected(); // Returns boolean
|
|
95
|
-
await client.reconnectWithConfig(partialConfig); // Reconnect with updated config
|
|
96
|
-
|
|
97
|
-
// Messaging
|
|
98
|
-
client.send(message); // Send message without waiting for response
|
|
99
|
-
await client.sendWithResponse(message, timeout); // Send and wait for response
|
|
100
|
-
await client.ask(message, { timeout }); // Alias for sendWithResponse
|
|
101
|
-
|
|
102
|
-
// Event handlers
|
|
103
|
-
client.onMessage((message) => { ... }); // Returns unsubscribe function
|
|
104
|
-
client.onConnect(() => { ... }); // Returns unsubscribe function
|
|
105
|
-
client.onDisconnect(() => { ... }); // Returns unsubscribe function
|
|
106
|
-
client.onError((error) => { ... }); // Returns unsubscribe function
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
### Service Methods
|
|
110
|
-
|
|
111
|
-
#### Authentication
|
|
112
|
-
|
|
113
|
-
```typescript
|
|
114
|
-
// Login with credentials
|
|
115
|
-
const loginResponse = await client.sendAuthLoginRequest(
|
|
116
|
-
loginDataBase64, // Base64 encoded: username + SHA-1 hashed password
|
|
117
|
-
timeout // Optional timeout in ms
|
|
118
|
-
);
|
|
119
|
-
|
|
120
|
-
// Verify authentication token
|
|
121
|
-
const verifyResponse = await client.sendAuthVerifyRequest(
|
|
122
|
-
token, // Base64 encoded auth token
|
|
123
|
-
timeout // Optional timeout in ms
|
|
124
|
-
);
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
#### User Management
|
|
128
|
-
|
|
129
|
-
```typescript
|
|
130
|
-
// Create a new user
|
|
131
|
-
const result = await client.createUser(
|
|
132
|
-
username,
|
|
133
|
-
password,
|
|
134
|
-
email?, // Optional: User email
|
|
135
|
-
fullname?, // Optional: User full name
|
|
136
|
-
role?, // Optional: User role
|
|
137
|
-
timeout?
|
|
138
|
-
);
|
|
139
|
-
// Returns: { success, username?, email?, fullname?, role?, message?, error? }
|
|
140
|
-
|
|
141
|
-
// Update an existing user
|
|
142
|
-
const result = await client.updateUser(
|
|
143
|
-
username,
|
|
144
|
-
{
|
|
145
|
-
password?: string, // Optional: New password
|
|
146
|
-
email?: string, // Optional: New email
|
|
147
|
-
fullname?: string, // Optional: New full name
|
|
148
|
-
role?: string, // Optional: New role
|
|
149
|
-
},
|
|
150
|
-
timeout?
|
|
151
|
-
);
|
|
152
|
-
// Returns: { success, username?, email?, fullname?, role?, message?, error? }
|
|
153
|
-
|
|
154
|
-
// Delete a user
|
|
155
|
-
const result = await client.deleteUser(username, timeout);
|
|
156
|
-
// Returns: { success, username?, email?, fullname?, role?, message?, error? }
|
|
157
|
-
|
|
158
|
-
// Get all users
|
|
159
|
-
const result = await client.getAllUsers(timeout);
|
|
160
|
-
// Returns: { success, users, count, error?, message? }
|
|
161
|
-
// User object: { username, email?, fullname?, role?, wsIds }
|
|
162
|
-
|
|
163
|
-
// Get a specific user
|
|
164
|
-
const result = await client.getUser(username, timeout);
|
|
165
|
-
// Returns: { success, user, error?, message? }
|
|
166
|
-
// User object: { username, email?, fullname?, role?, wsIds }
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
#### Dashboard Management
|
|
170
|
-
|
|
171
|
-
```typescript
|
|
172
|
-
// Create a new dashboard
|
|
173
|
-
const result = await client.createDashboard(
|
|
174
|
-
dashboardId,
|
|
175
|
-
dashboardConfig, // DSLRendererProps
|
|
176
|
-
timeout
|
|
177
|
-
);
|
|
178
|
-
|
|
179
|
-
// Update an existing dashboard
|
|
180
|
-
const result = await client.updateDashboard(
|
|
181
|
-
dashboardId,
|
|
182
|
-
dashboardConfig,
|
|
183
|
-
timeout
|
|
184
|
-
);
|
|
185
|
-
|
|
186
|
-
// Delete a dashboard
|
|
187
|
-
const result = await client.deleteDashboard(dashboardId, timeout);
|
|
188
|
-
|
|
189
|
-
// Get all dashboards
|
|
190
|
-
const result = await client.getAllDashboards(timeout);
|
|
191
|
-
// Returns: { success, dashboards, count, error?, message? }
|
|
192
|
-
|
|
193
|
-
// Get a specific dashboard
|
|
194
|
-
const result = await client.getDashboard(dashboardId, timeout);
|
|
195
|
-
// Returns: { success, dashboardId, dashboard, error?, message? }
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
#### Report Management
|
|
199
|
-
|
|
200
|
-
```typescript
|
|
201
|
-
// Create a new report
|
|
202
|
-
const result = await client.createReport(
|
|
203
|
-
reportId,
|
|
204
|
-
reportConfig, // ReportDSLRendererProps
|
|
205
|
-
timeout
|
|
206
|
-
);
|
|
207
|
-
|
|
208
|
-
// Update an existing report
|
|
209
|
-
const result = await client.updateReport(
|
|
210
|
-
reportId,
|
|
211
|
-
reportConfig,
|
|
212
|
-
timeout
|
|
213
|
-
);
|
|
214
|
-
|
|
215
|
-
// Delete a report
|
|
216
|
-
const result = await client.deleteReport(reportId, timeout);
|
|
217
|
-
|
|
218
|
-
// Get all reports
|
|
219
|
-
const result = await client.getAllReports(timeout);
|
|
220
|
-
// Returns: { success, reports, count, error?, message? }
|
|
221
|
-
|
|
222
|
-
// Get a specific report
|
|
223
|
-
const result = await client.getReport(reportId, timeout);
|
|
224
|
-
// Returns: { success, reportId, report, error?, message? }
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
#### User Prompts & AI Suggestions
|
|
228
|
-
|
|
229
|
-
```typescript
|
|
230
|
-
// Send a user prompt request (component mode - default)
|
|
231
|
-
const response = await client.sendUserPromptRequest(
|
|
232
|
-
prompt,
|
|
233
|
-
threadId,
|
|
234
|
-
uiBlockId,
|
|
235
|
-
'component', // responseMode: 'component' (default) or 'text'
|
|
236
|
-
undefined, // onStream callback (only used for text mode)
|
|
237
|
-
timeout
|
|
238
|
-
);
|
|
239
|
-
|
|
240
|
-
// Send a user prompt request with text streaming
|
|
241
|
-
const response = await client.sendUserPromptRequest(
|
|
242
|
-
prompt,
|
|
243
|
-
threadId,
|
|
244
|
-
uiBlockId,
|
|
245
|
-
'text', // responseMode: 'text' for streaming
|
|
246
|
-
(chunk) => { // onStream callback receives text chunks
|
|
247
|
-
console.log('Stream chunk:', chunk);
|
|
248
|
-
},
|
|
249
|
-
timeout
|
|
250
|
-
);
|
|
251
|
-
|
|
252
|
-
// Get AI component suggestions
|
|
253
|
-
const result = await client.sendUserPromptSuggestionsRequest(
|
|
254
|
-
'show me a form to collect user data',
|
|
255
|
-
5, // limit (default: 5)
|
|
256
|
-
timeout // optional timeout
|
|
257
|
-
);
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
#### Bundle & Data
|
|
261
|
-
|
|
262
|
-
```typescript
|
|
263
|
-
// Request bundle with progress tracking
|
|
264
|
-
const bundle = await client.requestBundle({
|
|
265
|
-
timeout: 60000,
|
|
266
|
-
onProgress: (progress) => {
|
|
267
|
-
console.log(`Download progress: ${progress}%`);
|
|
268
|
-
}
|
|
269
|
-
});
|
|
270
|
-
|
|
271
|
-
// Query data collections
|
|
272
|
-
const result = await client.requestData({
|
|
273
|
-
collection: 'users',
|
|
274
|
-
operation: 'getMany',
|
|
275
|
-
params: { limit: 10 },
|
|
276
|
-
timeout: 10000
|
|
277
|
-
});
|
|
278
|
-
// Returns: { data?, error? }
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
#### Actions API
|
|
282
|
-
|
|
283
|
-
```typescript
|
|
284
|
-
// Get available actions for the current context
|
|
285
|
-
const result = await client.getActions({
|
|
286
|
-
SA_RUNTIME: {
|
|
287
|
-
threadId: 'thread_123',
|
|
288
|
-
uiBlockId: 'block_456'
|
|
289
|
-
},
|
|
290
|
-
timeout: 10000
|
|
291
|
-
});
|
|
292
|
-
// Returns: { success, data?, error? }
|
|
293
|
-
```
|
|
294
|
-
|
|
295
|
-
#### Component Management
|
|
296
|
-
|
|
297
|
-
```typescript
|
|
298
|
-
// Send component list to server
|
|
299
|
-
await client.sendComponents([
|
|
300
|
-
{
|
|
301
|
-
id: 'comp_1',
|
|
302
|
-
name: 'MyComponent',
|
|
303
|
-
type: 'custom',
|
|
304
|
-
description: 'A custom component',
|
|
305
|
-
props: { /* ... */ }
|
|
306
|
-
},
|
|
307
|
-
// ... more components
|
|
308
|
-
]);
|
|
309
|
-
```
|
|
310
|
-
|
|
311
|
-
### Component Setup
|
|
312
|
-
|
|
313
|
-
Register your components with SuperAtom for dynamic rendering.
|
|
314
|
-
|
|
315
|
-
```typescript
|
|
316
|
-
import { setup } from '@superatomai/sdk-web';
|
|
317
|
-
import { createRoot } from 'react-dom/client';
|
|
318
|
-
import { createElement } from 'react';
|
|
319
|
-
|
|
320
|
-
setup({
|
|
321
|
-
// Your components
|
|
322
|
-
DemoCard: DemoCard,
|
|
323
|
-
Calendar: Calendar,
|
|
324
|
-
Form: ComplexForm,
|
|
325
|
-
|
|
326
|
-
// Mount function (required)
|
|
327
|
-
mount: (Component, container, props) => {
|
|
328
|
-
const root = createRoot(container);
|
|
329
|
-
root.render(createElement(Component, props));
|
|
330
|
-
return { unmount: () => root.unmount() };
|
|
331
|
-
}
|
|
332
|
-
});
|
|
333
|
-
```
|
|
334
|
-
|
|
335
|
-
## Message Types
|
|
336
|
-
|
|
337
|
-
The SDK supports the following message types (all validated with Zod schemas):
|
|
338
|
-
|
|
339
|
-
**Authentication**
|
|
340
|
-
- `AUTH_LOGIN_REQ` / `AUTH_LOGIN_RES` - User login
|
|
341
|
-
- `AUTH_VERIFY_REQ` / `AUTH_VERIFY_RES` - Token verification
|
|
342
|
-
|
|
343
|
-
**User Prompts & AI**
|
|
344
|
-
- `USER_PROMPT_REQ` / `USER_PROMPT_RES` - User prompt processing
|
|
345
|
-
- `USER_PROMPT_STREAM` - Real-time text streaming from AI responses
|
|
346
|
-
- `USER_PROMPT_SUGGESTIONS_REQ` / `USER_PROMPT_SUGGESTIONS_RES` - Component suggestions
|
|
347
|
-
|
|
348
|
-
**Bundle & Data**
|
|
349
|
-
- `BUNDLE_REQ` / `BUNDLE_CHUNK` - Bundle transfer with chunking
|
|
350
|
-
- `DATA_REQ` / `DATA_RES` - Data collection queries
|
|
351
|
-
|
|
352
|
-
**Management Operations**
|
|
353
|
-
- `USERS` / `USERS_RES` - User CRUD operations
|
|
354
|
-
- `DASHBOARDS` / `DASHBOARDS_RES` - Dashboard CRUD operations
|
|
355
|
-
- `REPORTS` / `REPORTS_RES` - Report CRUD operations
|
|
356
|
-
|
|
357
|
-
**Actions & Components**
|
|
358
|
-
- `ACTIONS` / `ACTIONS_RES` - Runtime actions API
|
|
359
|
-
- `COMPONENT_LIST_RES` - Send component list to server
|
|
360
|
-
|
|
361
|
-
**Logging**
|
|
362
|
-
- `UI_LOGS` - UI logging messages
|
|
363
|
-
|
|
364
|
-
All message types are fully typed and validated using Zod v4 schemas.
|
|
365
|
-
|
|
366
|
-
### USERS Schema
|
|
367
|
-
|
|
368
|
-
The USERS message type supports comprehensive user management with the following structure:
|
|
369
|
-
|
|
370
|
-
**Request Payload** (`USERS`):
|
|
371
|
-
```typescript
|
|
372
|
-
{
|
|
373
|
-
operation: 'create' | 'update' | 'delete' | 'getAll' | 'getOne',
|
|
374
|
-
data?: {
|
|
375
|
-
username?: string, // Required for all operations except getAll
|
|
376
|
-
email?: string, // Optional: User email (validated)
|
|
377
|
-
password?: string, // Required for create, optional for update
|
|
378
|
-
fullname?: string, // Optional: User's full name
|
|
379
|
-
role?: string, // Optional: User's role
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
```
|
|
383
|
-
|
|
384
|
-
**Response Payload** (`USERS_RES`):
|
|
385
|
-
```typescript
|
|
386
|
-
{
|
|
387
|
-
success: boolean,
|
|
388
|
-
error?: string,
|
|
389
|
-
data?: {
|
|
390
|
-
username?: string,
|
|
391
|
-
email?: string,
|
|
392
|
-
fullname?: string,
|
|
393
|
-
role?: string,
|
|
394
|
-
message?: string,
|
|
395
|
-
// For getAll operation
|
|
396
|
-
users?: Array<{
|
|
397
|
-
username: string,
|
|
398
|
-
email?: string,
|
|
399
|
-
fullname?: string,
|
|
400
|
-
role?: string,
|
|
401
|
-
wsIds: string[]
|
|
402
|
-
}>,
|
|
403
|
-
count?: number,
|
|
404
|
-
// For getOne operation
|
|
405
|
-
user?: {
|
|
406
|
-
username: string,
|
|
407
|
-
email?: string,
|
|
408
|
-
fullname?: string,
|
|
409
|
-
role?: string,
|
|
410
|
-
wsIds: string[]
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
```
|
|
415
|
-
|
|
416
|
-
**User Object Structure**:
|
|
417
|
-
```typescript
|
|
418
|
-
interface User {
|
|
419
|
-
username: string; // Required: Unique username
|
|
420
|
-
email?: string; // Optional: Validated email address
|
|
421
|
-
fullname?: string; // Optional: User's full name
|
|
422
|
-
role?: string; // Optional: User role (e.g., 'admin', 'editor', 'viewer')
|
|
423
|
-
wsIds: string[]; // WebSocket connection IDs (in-memory only)
|
|
424
|
-
}
|
|
425
|
-
```
|
|
426
|
-
|
|
427
|
-
## Type Safety
|
|
428
|
-
|
|
429
|
-
All messages are validated using Zod v4 schemas. The SDK exports comprehensive type definitions and schemas:
|
|
430
|
-
|
|
431
|
-
```typescript
|
|
432
|
-
import {
|
|
433
|
-
MessageSchema,
|
|
434
|
-
DataRequestMessageSchema,
|
|
435
|
-
AuthLoginRequestMessageSchema,
|
|
436
|
-
UserPromptSuggestionsRequestMessageSchema,
|
|
437
|
-
// ... and many more
|
|
438
|
-
} from '@superatomai/sdk-web';
|
|
439
|
-
|
|
440
|
-
// Validate any message
|
|
441
|
-
const validMessage = MessageSchema.parse(incomingData);
|
|
442
|
-
|
|
443
|
-
// Validate specific message types
|
|
444
|
-
const dataRequest = DataRequestMessageSchema.parse(requestData);
|
|
445
|
-
|
|
446
|
-
// TypeScript types are automatically inferred
|
|
447
|
-
import type {
|
|
448
|
-
Message,
|
|
449
|
-
DataRequestMessage,
|
|
450
|
-
AuthLoginResponseMessage,
|
|
451
|
-
Component,
|
|
452
|
-
DSLRendererProps,
|
|
453
|
-
ReportDSLRendererProps,
|
|
454
|
-
} from '@superatomai/sdk-web';
|
|
455
|
-
```
|
|
456
|
-
|
|
457
|
-
## Examples
|
|
458
|
-
|
|
459
|
-
### Complete React Integration
|
|
460
|
-
|
|
461
|
-
```typescript
|
|
462
|
-
import { SuperatomClient, setup } from '@superatomai/sdk-web';
|
|
463
|
-
import { createRoot } from 'react-dom/client';
|
|
464
|
-
import { createElement } from 'react';
|
|
465
|
-
import MyComponent from './components/MyComponent';
|
|
466
|
-
|
|
467
|
-
// Initialize client
|
|
468
|
-
const client = new SuperatomClient({
|
|
469
|
-
userId: 'user_123',
|
|
470
|
-
projectId: 'project_456',
|
|
471
|
-
type: 'runtime',
|
|
472
|
-
debug: true,
|
|
473
|
-
});
|
|
474
|
-
|
|
475
|
-
// Setup components
|
|
476
|
-
setup({
|
|
477
|
-
MyComponent,
|
|
478
|
-
mount: (Component, container, props) => {
|
|
479
|
-
const root = createRoot(container);
|
|
480
|
-
root.render(createElement(Component, props));
|
|
481
|
-
return { unmount: () => root.unmount() };
|
|
482
|
-
}
|
|
483
|
-
});
|
|
484
|
-
|
|
485
|
-
// Connect and authenticate
|
|
486
|
-
await client.connect();
|
|
487
|
-
|
|
488
|
-
// Listen for messages
|
|
489
|
-
client.onMessage((message) => {
|
|
490
|
-
console.log('Received:', message);
|
|
491
|
-
});
|
|
492
|
-
|
|
493
|
-
// Get component suggestions
|
|
494
|
-
async function handleUserQuery(query: string) {
|
|
495
|
-
const result = await client.sendUserPromptSuggestionsRequest(query, 5);
|
|
496
|
-
|
|
497
|
-
if (result?.payload?.data?.suggestions) {
|
|
498
|
-
console.log('Suggestions:', result.payload.data.suggestions);
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
```
|
|
502
|
-
|
|
503
|
-
### User Management Example
|
|
504
|
-
|
|
505
|
-
```typescript
|
|
506
|
-
import { SuperatomClient } from '@superatomai/sdk-web';
|
|
507
|
-
|
|
508
|
-
const client = new SuperatomClient({
|
|
509
|
-
userId: 'admin_123',
|
|
510
|
-
projectId: 'project_456',
|
|
511
|
-
});
|
|
512
|
-
|
|
513
|
-
await client.connect();
|
|
514
|
-
|
|
515
|
-
// Create a new user with all fields
|
|
516
|
-
const createResult = await client.createUser(
|
|
517
|
-
'newuser',
|
|
518
|
-
'password123',
|
|
519
|
-
'user@example.com', // email
|
|
520
|
-
'John Doe', // fullname
|
|
521
|
-
'editor' // role
|
|
522
|
-
);
|
|
523
|
-
if (createResult.success) {
|
|
524
|
-
console.log('User created:', createResult.username);
|
|
525
|
-
console.log('Email:', createResult.email);
|
|
526
|
-
console.log('Full name:', createResult.fullname);
|
|
527
|
-
console.log('Role:', createResult.role);
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
// Get all users
|
|
531
|
-
const usersResult = await client.getAllUsers();
|
|
532
|
-
if (usersResult.success && usersResult.users) {
|
|
533
|
-
console.log(`Found ${usersResult.count} users`);
|
|
534
|
-
usersResult.users.forEach(user => {
|
|
535
|
-
console.log(`- ${user.username} (${user.email || 'no email'})`);
|
|
536
|
-
console.log(` Full name: ${user.fullname || 'N/A'}`);
|
|
537
|
-
console.log(` Role: ${user.role || 'N/A'}`);
|
|
538
|
-
console.log(` Connections: ${user.wsIds.length}`);
|
|
539
|
-
});
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
// Update a user - change multiple fields
|
|
543
|
-
await client.updateUser('newuser', {
|
|
544
|
-
password: 'newpassword456',
|
|
545
|
-
email: 'newemail@example.com',
|
|
546
|
-
fullname: 'Jane Doe',
|
|
547
|
-
role: 'admin'
|
|
548
|
-
});
|
|
549
|
-
|
|
550
|
-
// Update a user - change only specific fields
|
|
551
|
-
await client.updateUser('newuser', {
|
|
552
|
-
role: 'viewer' // Only update role
|
|
553
|
-
});
|
|
554
|
-
|
|
555
|
-
// Delete a user
|
|
556
|
-
await client.deleteUser('newuser');
|
|
557
|
-
```
|
|
558
|
-
|
|
559
|
-
### Dashboard Management Example
|
|
560
|
-
|
|
561
|
-
```typescript
|
|
562
|
-
import { SuperatomClient } from '@superatomai/sdk-web';
|
|
563
|
-
import type { DSLRendererProps } from '@superatomai/sdk-web';
|
|
564
|
-
|
|
565
|
-
const client = new SuperatomClient({
|
|
566
|
-
userId: 'admin_123',
|
|
567
|
-
projectId: 'project_456',
|
|
568
|
-
});
|
|
569
|
-
|
|
570
|
-
await client.connect();
|
|
571
|
-
|
|
572
|
-
// Create a dashboard
|
|
573
|
-
const dashboardConfig: DSLRendererProps = {
|
|
574
|
-
// Your dashboard configuration
|
|
575
|
-
};
|
|
576
|
-
|
|
577
|
-
const result = await client.createDashboard(
|
|
578
|
-
'dashboard_001',
|
|
579
|
-
dashboardConfig
|
|
580
|
-
);
|
|
581
|
-
|
|
582
|
-
if (result.success) {
|
|
583
|
-
console.log('Dashboard created:', result.dashboardId);
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
// Get all dashboards
|
|
587
|
-
const dashboards = await client.getAllDashboards();
|
|
588
|
-
if (dashboards.success && dashboards.dashboards) {
|
|
589
|
-
console.log(`Total dashboards: ${dashboards.count}`);
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
// Get specific dashboard
|
|
593
|
-
const dashboard = await client.getDashboard('dashboard_001');
|
|
594
|
-
if (dashboard.success && dashboard.dashboard) {
|
|
595
|
-
console.log('Dashboard config:', dashboard.dashboard);
|
|
596
|
-
}
|
|
597
|
-
```
|
|
598
|
-
|
|
599
|
-
### Data Query Example
|
|
600
|
-
|
|
601
|
-
```typescript
|
|
602
|
-
import { SuperatomClient } from '@superatomai/sdk-web';
|
|
603
|
-
|
|
604
|
-
const client = new SuperatomClient({
|
|
605
|
-
userId: 'user_123',
|
|
606
|
-
projectId: 'project_456',
|
|
607
|
-
});
|
|
608
|
-
|
|
609
|
-
await client.connect();
|
|
610
|
-
|
|
611
|
-
// Query data from a collection
|
|
612
|
-
const result = await client.requestData({
|
|
613
|
-
collection: 'products',
|
|
614
|
-
operation: 'getMany',
|
|
615
|
-
params: {
|
|
616
|
-
filter: { category: 'electronics' },
|
|
617
|
-
limit: 20,
|
|
618
|
-
offset: 0
|
|
619
|
-
},
|
|
620
|
-
timeout: 10000
|
|
621
|
-
});
|
|
622
|
-
|
|
623
|
-
if (!result.error && result.data) {
|
|
624
|
-
console.log('Products:', result.data);
|
|
625
|
-
} else {
|
|
626
|
-
console.error('Error:', result.error);
|
|
627
|
-
}
|
|
628
|
-
```
|
|
629
|
-
|
|
630
|
-
### Text Streaming Example
|
|
631
|
-
|
|
632
|
-
```typescript
|
|
633
|
-
import { SuperatomClient } from '@superatomai/sdk-web';
|
|
634
|
-
|
|
635
|
-
const client = new SuperatomClient({
|
|
636
|
-
userId: 'user_123',
|
|
637
|
-
projectId: 'project_456',
|
|
638
|
-
});
|
|
639
|
-
|
|
640
|
-
await client.connect();
|
|
641
|
-
|
|
642
|
-
// Use text streaming for real-time AI responses
|
|
643
|
-
let streamedText = '';
|
|
644
|
-
|
|
645
|
-
const response = await client.sendUserPromptRequest(
|
|
646
|
-
'Explain how photosynthesis works',
|
|
647
|
-
'thread_123',
|
|
648
|
-
'block_456',
|
|
649
|
-
'text', // Enable text streaming mode
|
|
650
|
-
(chunk) => {
|
|
651
|
-
// Receive text chunks in real-time
|
|
652
|
-
streamedText += chunk;
|
|
653
|
-
console.log('Received chunk:', chunk);
|
|
654
|
-
// Update UI with streaming text
|
|
655
|
-
updateUIWithText(streamedText);
|
|
656
|
-
},
|
|
657
|
-
30000
|
|
658
|
-
);
|
|
659
|
-
|
|
660
|
-
console.log('Streaming complete. Final response:', response);
|
|
661
|
-
```
|
|
662
|
-
|
|
663
|
-
### Actions API Example
|
|
664
|
-
|
|
665
|
-
```typescript
|
|
666
|
-
import { SuperatomClient } from '@superatomai/sdk-web';
|
|
667
|
-
|
|
668
|
-
const client = new SuperatomClient({
|
|
669
|
-
userId: 'user_123',
|
|
670
|
-
projectId: 'project_456',
|
|
671
|
-
});
|
|
672
|
-
|
|
673
|
-
await client.connect();
|
|
674
|
-
|
|
675
|
-
// Get available actions for the current runtime context
|
|
676
|
-
const result = await client.getActions({
|
|
677
|
-
SA_RUNTIME: {
|
|
678
|
-
threadId: 'thread_123',
|
|
679
|
-
uiBlockId: 'block_456'
|
|
680
|
-
},
|
|
681
|
-
timeout: 10000
|
|
682
|
-
});
|
|
683
|
-
|
|
684
|
-
if (result.success && result.data) {
|
|
685
|
-
console.log('Available actions:', result.data);
|
|
686
|
-
} else {
|
|
687
|
-
console.error('Error:', result.error);
|
|
688
|
-
}
|
|
689
|
-
|
|
690
|
-
// Send component list to server
|
|
691
|
-
await client.sendComponents([
|
|
692
|
-
{
|
|
693
|
-
id: 'my_component_1',
|
|
694
|
-
name: 'DataTable',
|
|
695
|
-
type: 'table',
|
|
696
|
-
description: 'Display data in table format',
|
|
697
|
-
props: {
|
|
698
|
-
columns: ['name', 'email', 'status'],
|
|
699
|
-
data: []
|
|
700
|
-
}
|
|
701
|
-
}
|
|
702
|
-
]);
|
|
703
|
-
```
|
|
704
|
-
|
|
705
|
-
## Advanced Usage
|
|
706
|
-
|
|
707
|
-
### Direct Service Access
|
|
708
|
-
|
|
709
|
-
All service functions can be imported and used directly for advanced use cases:
|
|
710
|
-
|
|
711
|
-
```typescript
|
|
712
|
-
import { SuperatomClient, services } from '@superatomai/sdk-web';
|
|
713
|
-
|
|
714
|
-
const client = new SuperatomClient({ /* ... */ });
|
|
715
|
-
|
|
716
|
-
// Use service functions directly
|
|
717
|
-
const result = await services.requestData(client, {
|
|
718
|
-
collection: 'users',
|
|
719
|
-
operation: 'getMany',
|
|
720
|
-
params: {},
|
|
721
|
-
timeout: 10000
|
|
722
|
-
});
|
|
723
|
-
```
|
|
724
|
-
|
|
725
|
-
### Event Unsubscription
|
|
726
|
-
|
|
727
|
-
All event handlers return an unsubscribe function:
|
|
728
|
-
|
|
729
|
-
```typescript
|
|
730
|
-
const unsubscribe = client.onMessage((message) => {
|
|
731
|
-
console.log('Message:', message);
|
|
732
|
-
});
|
|
733
|
-
|
|
734
|
-
// Later, when you want to stop listening
|
|
735
|
-
unsubscribe();
|
|
736
|
-
```
|
|
737
|
-
|
|
738
|
-
### Reconnection with Updated Config
|
|
739
|
-
|
|
740
|
-
You can reconnect with updated configuration without creating a new client:
|
|
741
|
-
|
|
742
|
-
```typescript
|
|
743
|
-
await client.reconnectWithConfig({
|
|
744
|
-
userId: 'new_user_id',
|
|
745
|
-
debug: true
|
|
746
|
-
});
|
|
747
|
-
```
|
|
748
|
-
|
|
749
|
-
## License
|
|
750
|
-
|
|
751
|
-
MIT
|
|
752
|
-
|
|
753
|
-
## Support
|
|
754
|
-
|
|
755
|
-
For issues and questions, please contact the SuperAtom team or refer to the SuperAtom platform documentation.
|
|
1
|
+
# @superatomai/sdk-web
|
|
2
|
+
|
|
3
|
+
SuperAtom Web SDK - TypeScript SDK for browser-based WebSocket communication with the SuperAtom platform.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🔌 WebSocket client with automatic reconnection and exponential backoff
|
|
8
|
+
- 🔒 Type-safe message validation using Zod v4
|
|
9
|
+
- 🎯 Request/response pattern with timeout support
|
|
10
|
+
- 📦 Bundle management with chunked transfer
|
|
11
|
+
- 🧩 Component registration and communication system
|
|
12
|
+
- 🔐 Authentication (login and token verification)
|
|
13
|
+
- 👥 User management (CRUD operations)
|
|
14
|
+
- 📊 Dashboard management (CRUD operations)
|
|
15
|
+
- 📈 Report management (CRUD operations)
|
|
16
|
+
- 🤖 AI component suggestions with text streaming support
|
|
17
|
+
- 💾 Data collection queries
|
|
18
|
+
- ⚡ Actions API for runtime operations
|
|
19
|
+
- 📝 UI logging support
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pnpm add @superatomai/sdk-web
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Quick Start
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
import { SuperatomClient, setup } from '@superatomai/sdk-web';
|
|
31
|
+
|
|
32
|
+
// 1. Create and connect client
|
|
33
|
+
const client = new SuperatomClient({
|
|
34
|
+
userId: 'your-user-id',
|
|
35
|
+
projectId: 'your-project-id',
|
|
36
|
+
type: 'runtime', // Connection type (default: 'runtime')
|
|
37
|
+
debug: true, // Enable debug logging
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
await client.connect();
|
|
41
|
+
|
|
42
|
+
// 2. Setup components (optional - for component rendering)
|
|
43
|
+
setup({
|
|
44
|
+
MyComponent: MyReactComponent,
|
|
45
|
+
AnotherComponent: AnotherReactComponent,
|
|
46
|
+
mount: (Component, container, props) => {
|
|
47
|
+
const root = createRoot(container);
|
|
48
|
+
root.render(createElement(Component, props));
|
|
49
|
+
return { unmount: () => root.unmount() };
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// 3. Authenticate (optional)
|
|
54
|
+
const loginResponse = await client.sendAuthLoginRequest(
|
|
55
|
+
loginDataBase64, // Base64 encoded login data
|
|
56
|
+
10000 // timeout in ms
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
// 4. Get AI component suggestions
|
|
60
|
+
const result = await client.sendUserPromptSuggestionsRequest(
|
|
61
|
+
'show me a calendar component',
|
|
62
|
+
5 // limit
|
|
63
|
+
);
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## API Reference
|
|
67
|
+
|
|
68
|
+
### SuperatomClient
|
|
69
|
+
|
|
70
|
+
Main WebSocket client for communication.
|
|
71
|
+
|
|
72
|
+
#### Configuration
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
const client = new SuperatomClient({
|
|
76
|
+
userId: string, // Required: User ID
|
|
77
|
+
projectId: string, // Required: Project ID
|
|
78
|
+
type?: string, // Default: 'runtime'
|
|
79
|
+
baseUrl?: string, // Default: 'wss://ws.superatom.ai/websocket'
|
|
80
|
+
maxReconnectAttempts?: number, // Default: Infinity
|
|
81
|
+
initialReconnectDelay?: number, // Default: 1000ms
|
|
82
|
+
maxReconnectDelay?: number, // Default: 30000ms
|
|
83
|
+
defaultTimeout?: number, // Default: 30000ms
|
|
84
|
+
debug?: boolean, // Default: false
|
|
85
|
+
});
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
#### Core Methods
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
// Connection management
|
|
92
|
+
await client.connect(); // Returns Promise<void>
|
|
93
|
+
client.disconnect();
|
|
94
|
+
client.isConnected(); // Returns boolean
|
|
95
|
+
await client.reconnectWithConfig(partialConfig); // Reconnect with updated config
|
|
96
|
+
|
|
97
|
+
// Messaging
|
|
98
|
+
client.send(message); // Send message without waiting for response
|
|
99
|
+
await client.sendWithResponse(message, timeout); // Send and wait for response
|
|
100
|
+
await client.ask(message, { timeout }); // Alias for sendWithResponse
|
|
101
|
+
|
|
102
|
+
// Event handlers
|
|
103
|
+
client.onMessage((message) => { ... }); // Returns unsubscribe function
|
|
104
|
+
client.onConnect(() => { ... }); // Returns unsubscribe function
|
|
105
|
+
client.onDisconnect(() => { ... }); // Returns unsubscribe function
|
|
106
|
+
client.onError((error) => { ... }); // Returns unsubscribe function
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Service Methods
|
|
110
|
+
|
|
111
|
+
#### Authentication
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
// Login with credentials
|
|
115
|
+
const loginResponse = await client.sendAuthLoginRequest(
|
|
116
|
+
loginDataBase64, // Base64 encoded: username + SHA-1 hashed password
|
|
117
|
+
timeout // Optional timeout in ms
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
// Verify authentication token
|
|
121
|
+
const verifyResponse = await client.sendAuthVerifyRequest(
|
|
122
|
+
token, // Base64 encoded auth token
|
|
123
|
+
timeout // Optional timeout in ms
|
|
124
|
+
);
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
#### User Management
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
// Create a new user
|
|
131
|
+
const result = await client.createUser(
|
|
132
|
+
username,
|
|
133
|
+
password,
|
|
134
|
+
email?, // Optional: User email
|
|
135
|
+
fullname?, // Optional: User full name
|
|
136
|
+
role?, // Optional: User role
|
|
137
|
+
timeout?
|
|
138
|
+
);
|
|
139
|
+
// Returns: { success, username?, email?, fullname?, role?, message?, error? }
|
|
140
|
+
|
|
141
|
+
// Update an existing user
|
|
142
|
+
const result = await client.updateUser(
|
|
143
|
+
username,
|
|
144
|
+
{
|
|
145
|
+
password?: string, // Optional: New password
|
|
146
|
+
email?: string, // Optional: New email
|
|
147
|
+
fullname?: string, // Optional: New full name
|
|
148
|
+
role?: string, // Optional: New role
|
|
149
|
+
},
|
|
150
|
+
timeout?
|
|
151
|
+
);
|
|
152
|
+
// Returns: { success, username?, email?, fullname?, role?, message?, error? }
|
|
153
|
+
|
|
154
|
+
// Delete a user
|
|
155
|
+
const result = await client.deleteUser(username, timeout);
|
|
156
|
+
// Returns: { success, username?, email?, fullname?, role?, message?, error? }
|
|
157
|
+
|
|
158
|
+
// Get all users
|
|
159
|
+
const result = await client.getAllUsers(timeout);
|
|
160
|
+
// Returns: { success, users, count, error?, message? }
|
|
161
|
+
// User object: { username, email?, fullname?, role?, wsIds }
|
|
162
|
+
|
|
163
|
+
// Get a specific user
|
|
164
|
+
const result = await client.getUser(username, timeout);
|
|
165
|
+
// Returns: { success, user, error?, message? }
|
|
166
|
+
// User object: { username, email?, fullname?, role?, wsIds }
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
#### Dashboard Management
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
// Create a new dashboard
|
|
173
|
+
const result = await client.createDashboard(
|
|
174
|
+
dashboardId,
|
|
175
|
+
dashboardConfig, // DSLRendererProps
|
|
176
|
+
timeout
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
// Update an existing dashboard
|
|
180
|
+
const result = await client.updateDashboard(
|
|
181
|
+
dashboardId,
|
|
182
|
+
dashboardConfig,
|
|
183
|
+
timeout
|
|
184
|
+
);
|
|
185
|
+
|
|
186
|
+
// Delete a dashboard
|
|
187
|
+
const result = await client.deleteDashboard(dashboardId, timeout);
|
|
188
|
+
|
|
189
|
+
// Get all dashboards
|
|
190
|
+
const result = await client.getAllDashboards(timeout);
|
|
191
|
+
// Returns: { success, dashboards, count, error?, message? }
|
|
192
|
+
|
|
193
|
+
// Get a specific dashboard
|
|
194
|
+
const result = await client.getDashboard(dashboardId, timeout);
|
|
195
|
+
// Returns: { success, dashboardId, dashboard, error?, message? }
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
#### Report Management
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
// Create a new report
|
|
202
|
+
const result = await client.createReport(
|
|
203
|
+
reportId,
|
|
204
|
+
reportConfig, // ReportDSLRendererProps
|
|
205
|
+
timeout
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
// Update an existing report
|
|
209
|
+
const result = await client.updateReport(
|
|
210
|
+
reportId,
|
|
211
|
+
reportConfig,
|
|
212
|
+
timeout
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
// Delete a report
|
|
216
|
+
const result = await client.deleteReport(reportId, timeout);
|
|
217
|
+
|
|
218
|
+
// Get all reports
|
|
219
|
+
const result = await client.getAllReports(timeout);
|
|
220
|
+
// Returns: { success, reports, count, error?, message? }
|
|
221
|
+
|
|
222
|
+
// Get a specific report
|
|
223
|
+
const result = await client.getReport(reportId, timeout);
|
|
224
|
+
// Returns: { success, reportId, report, error?, message? }
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
#### User Prompts & AI Suggestions
|
|
228
|
+
|
|
229
|
+
```typescript
|
|
230
|
+
// Send a user prompt request (component mode - default)
|
|
231
|
+
const response = await client.sendUserPromptRequest(
|
|
232
|
+
prompt,
|
|
233
|
+
threadId,
|
|
234
|
+
uiBlockId,
|
|
235
|
+
'component', // responseMode: 'component' (default) or 'text'
|
|
236
|
+
undefined, // onStream callback (only used for text mode)
|
|
237
|
+
timeout
|
|
238
|
+
);
|
|
239
|
+
|
|
240
|
+
// Send a user prompt request with text streaming
|
|
241
|
+
const response = await client.sendUserPromptRequest(
|
|
242
|
+
prompt,
|
|
243
|
+
threadId,
|
|
244
|
+
uiBlockId,
|
|
245
|
+
'text', // responseMode: 'text' for streaming
|
|
246
|
+
(chunk) => { // onStream callback receives text chunks
|
|
247
|
+
console.log('Stream chunk:', chunk);
|
|
248
|
+
},
|
|
249
|
+
timeout
|
|
250
|
+
);
|
|
251
|
+
|
|
252
|
+
// Get AI component suggestions
|
|
253
|
+
const result = await client.sendUserPromptSuggestionsRequest(
|
|
254
|
+
'show me a form to collect user data',
|
|
255
|
+
5, // limit (default: 5)
|
|
256
|
+
timeout // optional timeout
|
|
257
|
+
);
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
#### Bundle & Data
|
|
261
|
+
|
|
262
|
+
```typescript
|
|
263
|
+
// Request bundle with progress tracking
|
|
264
|
+
const bundle = await client.requestBundle({
|
|
265
|
+
timeout: 60000,
|
|
266
|
+
onProgress: (progress) => {
|
|
267
|
+
console.log(`Download progress: ${progress}%`);
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
// Query data collections
|
|
272
|
+
const result = await client.requestData({
|
|
273
|
+
collection: 'users',
|
|
274
|
+
operation: 'getMany',
|
|
275
|
+
params: { limit: 10 },
|
|
276
|
+
timeout: 10000
|
|
277
|
+
});
|
|
278
|
+
// Returns: { data?, error? }
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
#### Actions API
|
|
282
|
+
|
|
283
|
+
```typescript
|
|
284
|
+
// Get available actions for the current context
|
|
285
|
+
const result = await client.getActions({
|
|
286
|
+
SA_RUNTIME: {
|
|
287
|
+
threadId: 'thread_123',
|
|
288
|
+
uiBlockId: 'block_456'
|
|
289
|
+
},
|
|
290
|
+
timeout: 10000
|
|
291
|
+
});
|
|
292
|
+
// Returns: { success, data?, error? }
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
#### Component Management
|
|
296
|
+
|
|
297
|
+
```typescript
|
|
298
|
+
// Send component list to server
|
|
299
|
+
await client.sendComponents([
|
|
300
|
+
{
|
|
301
|
+
id: 'comp_1',
|
|
302
|
+
name: 'MyComponent',
|
|
303
|
+
type: 'custom',
|
|
304
|
+
description: 'A custom component',
|
|
305
|
+
props: { /* ... */ }
|
|
306
|
+
},
|
|
307
|
+
// ... more components
|
|
308
|
+
]);
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### Component Setup
|
|
312
|
+
|
|
313
|
+
Register your components with SuperAtom for dynamic rendering.
|
|
314
|
+
|
|
315
|
+
```typescript
|
|
316
|
+
import { setup } from '@superatomai/sdk-web';
|
|
317
|
+
import { createRoot } from 'react-dom/client';
|
|
318
|
+
import { createElement } from 'react';
|
|
319
|
+
|
|
320
|
+
setup({
|
|
321
|
+
// Your components
|
|
322
|
+
DemoCard: DemoCard,
|
|
323
|
+
Calendar: Calendar,
|
|
324
|
+
Form: ComplexForm,
|
|
325
|
+
|
|
326
|
+
// Mount function (required)
|
|
327
|
+
mount: (Component, container, props) => {
|
|
328
|
+
const root = createRoot(container);
|
|
329
|
+
root.render(createElement(Component, props));
|
|
330
|
+
return { unmount: () => root.unmount() };
|
|
331
|
+
}
|
|
332
|
+
});
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
## Message Types
|
|
336
|
+
|
|
337
|
+
The SDK supports the following message types (all validated with Zod schemas):
|
|
338
|
+
|
|
339
|
+
**Authentication**
|
|
340
|
+
- `AUTH_LOGIN_REQ` / `AUTH_LOGIN_RES` - User login
|
|
341
|
+
- `AUTH_VERIFY_REQ` / `AUTH_VERIFY_RES` - Token verification
|
|
342
|
+
|
|
343
|
+
**User Prompts & AI**
|
|
344
|
+
- `USER_PROMPT_REQ` / `USER_PROMPT_RES` - User prompt processing
|
|
345
|
+
- `USER_PROMPT_STREAM` - Real-time text streaming from AI responses
|
|
346
|
+
- `USER_PROMPT_SUGGESTIONS_REQ` / `USER_PROMPT_SUGGESTIONS_RES` - Component suggestions
|
|
347
|
+
|
|
348
|
+
**Bundle & Data**
|
|
349
|
+
- `BUNDLE_REQ` / `BUNDLE_CHUNK` - Bundle transfer with chunking
|
|
350
|
+
- `DATA_REQ` / `DATA_RES` - Data collection queries
|
|
351
|
+
|
|
352
|
+
**Management Operations**
|
|
353
|
+
- `USERS` / `USERS_RES` - User CRUD operations
|
|
354
|
+
- `DASHBOARDS` / `DASHBOARDS_RES` - Dashboard CRUD operations
|
|
355
|
+
- `REPORTS` / `REPORTS_RES` - Report CRUD operations
|
|
356
|
+
|
|
357
|
+
**Actions & Components**
|
|
358
|
+
- `ACTIONS` / `ACTIONS_RES` - Runtime actions API
|
|
359
|
+
- `COMPONENT_LIST_RES` - Send component list to server
|
|
360
|
+
|
|
361
|
+
**Logging**
|
|
362
|
+
- `UI_LOGS` - UI logging messages
|
|
363
|
+
|
|
364
|
+
All message types are fully typed and validated using Zod v4 schemas.
|
|
365
|
+
|
|
366
|
+
### USERS Schema
|
|
367
|
+
|
|
368
|
+
The USERS message type supports comprehensive user management with the following structure:
|
|
369
|
+
|
|
370
|
+
**Request Payload** (`USERS`):
|
|
371
|
+
```typescript
|
|
372
|
+
{
|
|
373
|
+
operation: 'create' | 'update' | 'delete' | 'getAll' | 'getOne',
|
|
374
|
+
data?: {
|
|
375
|
+
username?: string, // Required for all operations except getAll
|
|
376
|
+
email?: string, // Optional: User email (validated)
|
|
377
|
+
password?: string, // Required for create, optional for update
|
|
378
|
+
fullname?: string, // Optional: User's full name
|
|
379
|
+
role?: string, // Optional: User's role
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
**Response Payload** (`USERS_RES`):
|
|
385
|
+
```typescript
|
|
386
|
+
{
|
|
387
|
+
success: boolean,
|
|
388
|
+
error?: string,
|
|
389
|
+
data?: {
|
|
390
|
+
username?: string,
|
|
391
|
+
email?: string,
|
|
392
|
+
fullname?: string,
|
|
393
|
+
role?: string,
|
|
394
|
+
message?: string,
|
|
395
|
+
// For getAll operation
|
|
396
|
+
users?: Array<{
|
|
397
|
+
username: string,
|
|
398
|
+
email?: string,
|
|
399
|
+
fullname?: string,
|
|
400
|
+
role?: string,
|
|
401
|
+
wsIds: string[]
|
|
402
|
+
}>,
|
|
403
|
+
count?: number,
|
|
404
|
+
// For getOne operation
|
|
405
|
+
user?: {
|
|
406
|
+
username: string,
|
|
407
|
+
email?: string,
|
|
408
|
+
fullname?: string,
|
|
409
|
+
role?: string,
|
|
410
|
+
wsIds: string[]
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
**User Object Structure**:
|
|
417
|
+
```typescript
|
|
418
|
+
interface User {
|
|
419
|
+
username: string; // Required: Unique username
|
|
420
|
+
email?: string; // Optional: Validated email address
|
|
421
|
+
fullname?: string; // Optional: User's full name
|
|
422
|
+
role?: string; // Optional: User role (e.g., 'admin', 'editor', 'viewer')
|
|
423
|
+
wsIds: string[]; // WebSocket connection IDs (in-memory only)
|
|
424
|
+
}
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
## Type Safety
|
|
428
|
+
|
|
429
|
+
All messages are validated using Zod v4 schemas. The SDK exports comprehensive type definitions and schemas:
|
|
430
|
+
|
|
431
|
+
```typescript
|
|
432
|
+
import {
|
|
433
|
+
MessageSchema,
|
|
434
|
+
DataRequestMessageSchema,
|
|
435
|
+
AuthLoginRequestMessageSchema,
|
|
436
|
+
UserPromptSuggestionsRequestMessageSchema,
|
|
437
|
+
// ... and many more
|
|
438
|
+
} from '@superatomai/sdk-web';
|
|
439
|
+
|
|
440
|
+
// Validate any message
|
|
441
|
+
const validMessage = MessageSchema.parse(incomingData);
|
|
442
|
+
|
|
443
|
+
// Validate specific message types
|
|
444
|
+
const dataRequest = DataRequestMessageSchema.parse(requestData);
|
|
445
|
+
|
|
446
|
+
// TypeScript types are automatically inferred
|
|
447
|
+
import type {
|
|
448
|
+
Message,
|
|
449
|
+
DataRequestMessage,
|
|
450
|
+
AuthLoginResponseMessage,
|
|
451
|
+
Component,
|
|
452
|
+
DSLRendererProps,
|
|
453
|
+
ReportDSLRendererProps,
|
|
454
|
+
} from '@superatomai/sdk-web';
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
## Examples
|
|
458
|
+
|
|
459
|
+
### Complete React Integration
|
|
460
|
+
|
|
461
|
+
```typescript
|
|
462
|
+
import { SuperatomClient, setup } from '@superatomai/sdk-web';
|
|
463
|
+
import { createRoot } from 'react-dom/client';
|
|
464
|
+
import { createElement } from 'react';
|
|
465
|
+
import MyComponent from './components/MyComponent';
|
|
466
|
+
|
|
467
|
+
// Initialize client
|
|
468
|
+
const client = new SuperatomClient({
|
|
469
|
+
userId: 'user_123',
|
|
470
|
+
projectId: 'project_456',
|
|
471
|
+
type: 'runtime',
|
|
472
|
+
debug: true,
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
// Setup components
|
|
476
|
+
setup({
|
|
477
|
+
MyComponent,
|
|
478
|
+
mount: (Component, container, props) => {
|
|
479
|
+
const root = createRoot(container);
|
|
480
|
+
root.render(createElement(Component, props));
|
|
481
|
+
return { unmount: () => root.unmount() };
|
|
482
|
+
}
|
|
483
|
+
});
|
|
484
|
+
|
|
485
|
+
// Connect and authenticate
|
|
486
|
+
await client.connect();
|
|
487
|
+
|
|
488
|
+
// Listen for messages
|
|
489
|
+
client.onMessage((message) => {
|
|
490
|
+
console.log('Received:', message);
|
|
491
|
+
});
|
|
492
|
+
|
|
493
|
+
// Get component suggestions
|
|
494
|
+
async function handleUserQuery(query: string) {
|
|
495
|
+
const result = await client.sendUserPromptSuggestionsRequest(query, 5);
|
|
496
|
+
|
|
497
|
+
if (result?.payload?.data?.suggestions) {
|
|
498
|
+
console.log('Suggestions:', result.payload.data.suggestions);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
### User Management Example
|
|
504
|
+
|
|
505
|
+
```typescript
|
|
506
|
+
import { SuperatomClient } from '@superatomai/sdk-web';
|
|
507
|
+
|
|
508
|
+
const client = new SuperatomClient({
|
|
509
|
+
userId: 'admin_123',
|
|
510
|
+
projectId: 'project_456',
|
|
511
|
+
});
|
|
512
|
+
|
|
513
|
+
await client.connect();
|
|
514
|
+
|
|
515
|
+
// Create a new user with all fields
|
|
516
|
+
const createResult = await client.createUser(
|
|
517
|
+
'newuser',
|
|
518
|
+
'password123',
|
|
519
|
+
'user@example.com', // email
|
|
520
|
+
'John Doe', // fullname
|
|
521
|
+
'editor' // role
|
|
522
|
+
);
|
|
523
|
+
if (createResult.success) {
|
|
524
|
+
console.log('User created:', createResult.username);
|
|
525
|
+
console.log('Email:', createResult.email);
|
|
526
|
+
console.log('Full name:', createResult.fullname);
|
|
527
|
+
console.log('Role:', createResult.role);
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
// Get all users
|
|
531
|
+
const usersResult = await client.getAllUsers();
|
|
532
|
+
if (usersResult.success && usersResult.users) {
|
|
533
|
+
console.log(`Found ${usersResult.count} users`);
|
|
534
|
+
usersResult.users.forEach(user => {
|
|
535
|
+
console.log(`- ${user.username} (${user.email || 'no email'})`);
|
|
536
|
+
console.log(` Full name: ${user.fullname || 'N/A'}`);
|
|
537
|
+
console.log(` Role: ${user.role || 'N/A'}`);
|
|
538
|
+
console.log(` Connections: ${user.wsIds.length}`);
|
|
539
|
+
});
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
// Update a user - change multiple fields
|
|
543
|
+
await client.updateUser('newuser', {
|
|
544
|
+
password: 'newpassword456',
|
|
545
|
+
email: 'newemail@example.com',
|
|
546
|
+
fullname: 'Jane Doe',
|
|
547
|
+
role: 'admin'
|
|
548
|
+
});
|
|
549
|
+
|
|
550
|
+
// Update a user - change only specific fields
|
|
551
|
+
await client.updateUser('newuser', {
|
|
552
|
+
role: 'viewer' // Only update role
|
|
553
|
+
});
|
|
554
|
+
|
|
555
|
+
// Delete a user
|
|
556
|
+
await client.deleteUser('newuser');
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
### Dashboard Management Example
|
|
560
|
+
|
|
561
|
+
```typescript
|
|
562
|
+
import { SuperatomClient } from '@superatomai/sdk-web';
|
|
563
|
+
import type { DSLRendererProps } from '@superatomai/sdk-web';
|
|
564
|
+
|
|
565
|
+
const client = new SuperatomClient({
|
|
566
|
+
userId: 'admin_123',
|
|
567
|
+
projectId: 'project_456',
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
await client.connect();
|
|
571
|
+
|
|
572
|
+
// Create a dashboard
|
|
573
|
+
const dashboardConfig: DSLRendererProps = {
|
|
574
|
+
// Your dashboard configuration
|
|
575
|
+
};
|
|
576
|
+
|
|
577
|
+
const result = await client.createDashboard(
|
|
578
|
+
'dashboard_001',
|
|
579
|
+
dashboardConfig
|
|
580
|
+
);
|
|
581
|
+
|
|
582
|
+
if (result.success) {
|
|
583
|
+
console.log('Dashboard created:', result.dashboardId);
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
// Get all dashboards
|
|
587
|
+
const dashboards = await client.getAllDashboards();
|
|
588
|
+
if (dashboards.success && dashboards.dashboards) {
|
|
589
|
+
console.log(`Total dashboards: ${dashboards.count}`);
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
// Get specific dashboard
|
|
593
|
+
const dashboard = await client.getDashboard('dashboard_001');
|
|
594
|
+
if (dashboard.success && dashboard.dashboard) {
|
|
595
|
+
console.log('Dashboard config:', dashboard.dashboard);
|
|
596
|
+
}
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
### Data Query Example
|
|
600
|
+
|
|
601
|
+
```typescript
|
|
602
|
+
import { SuperatomClient } from '@superatomai/sdk-web';
|
|
603
|
+
|
|
604
|
+
const client = new SuperatomClient({
|
|
605
|
+
userId: 'user_123',
|
|
606
|
+
projectId: 'project_456',
|
|
607
|
+
});
|
|
608
|
+
|
|
609
|
+
await client.connect();
|
|
610
|
+
|
|
611
|
+
// Query data from a collection
|
|
612
|
+
const result = await client.requestData({
|
|
613
|
+
collection: 'products',
|
|
614
|
+
operation: 'getMany',
|
|
615
|
+
params: {
|
|
616
|
+
filter: { category: 'electronics' },
|
|
617
|
+
limit: 20,
|
|
618
|
+
offset: 0
|
|
619
|
+
},
|
|
620
|
+
timeout: 10000
|
|
621
|
+
});
|
|
622
|
+
|
|
623
|
+
if (!result.error && result.data) {
|
|
624
|
+
console.log('Products:', result.data);
|
|
625
|
+
} else {
|
|
626
|
+
console.error('Error:', result.error);
|
|
627
|
+
}
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
### Text Streaming Example
|
|
631
|
+
|
|
632
|
+
```typescript
|
|
633
|
+
import { SuperatomClient } from '@superatomai/sdk-web';
|
|
634
|
+
|
|
635
|
+
const client = new SuperatomClient({
|
|
636
|
+
userId: 'user_123',
|
|
637
|
+
projectId: 'project_456',
|
|
638
|
+
});
|
|
639
|
+
|
|
640
|
+
await client.connect();
|
|
641
|
+
|
|
642
|
+
// Use text streaming for real-time AI responses
|
|
643
|
+
let streamedText = '';
|
|
644
|
+
|
|
645
|
+
const response = await client.sendUserPromptRequest(
|
|
646
|
+
'Explain how photosynthesis works',
|
|
647
|
+
'thread_123',
|
|
648
|
+
'block_456',
|
|
649
|
+
'text', // Enable text streaming mode
|
|
650
|
+
(chunk) => {
|
|
651
|
+
// Receive text chunks in real-time
|
|
652
|
+
streamedText += chunk;
|
|
653
|
+
console.log('Received chunk:', chunk);
|
|
654
|
+
// Update UI with streaming text
|
|
655
|
+
updateUIWithText(streamedText);
|
|
656
|
+
},
|
|
657
|
+
30000
|
|
658
|
+
);
|
|
659
|
+
|
|
660
|
+
console.log('Streaming complete. Final response:', response);
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
### Actions API Example
|
|
664
|
+
|
|
665
|
+
```typescript
|
|
666
|
+
import { SuperatomClient } from '@superatomai/sdk-web';
|
|
667
|
+
|
|
668
|
+
const client = new SuperatomClient({
|
|
669
|
+
userId: 'user_123',
|
|
670
|
+
projectId: 'project_456',
|
|
671
|
+
});
|
|
672
|
+
|
|
673
|
+
await client.connect();
|
|
674
|
+
|
|
675
|
+
// Get available actions for the current runtime context
|
|
676
|
+
const result = await client.getActions({
|
|
677
|
+
SA_RUNTIME: {
|
|
678
|
+
threadId: 'thread_123',
|
|
679
|
+
uiBlockId: 'block_456'
|
|
680
|
+
},
|
|
681
|
+
timeout: 10000
|
|
682
|
+
});
|
|
683
|
+
|
|
684
|
+
if (result.success && result.data) {
|
|
685
|
+
console.log('Available actions:', result.data);
|
|
686
|
+
} else {
|
|
687
|
+
console.error('Error:', result.error);
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
// Send component list to server
|
|
691
|
+
await client.sendComponents([
|
|
692
|
+
{
|
|
693
|
+
id: 'my_component_1',
|
|
694
|
+
name: 'DataTable',
|
|
695
|
+
type: 'table',
|
|
696
|
+
description: 'Display data in table format',
|
|
697
|
+
props: {
|
|
698
|
+
columns: ['name', 'email', 'status'],
|
|
699
|
+
data: []
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
]);
|
|
703
|
+
```
|
|
704
|
+
|
|
705
|
+
## Advanced Usage
|
|
706
|
+
|
|
707
|
+
### Direct Service Access
|
|
708
|
+
|
|
709
|
+
All service functions can be imported and used directly for advanced use cases:
|
|
710
|
+
|
|
711
|
+
```typescript
|
|
712
|
+
import { SuperatomClient, services } from '@superatomai/sdk-web';
|
|
713
|
+
|
|
714
|
+
const client = new SuperatomClient({ /* ... */ });
|
|
715
|
+
|
|
716
|
+
// Use service functions directly
|
|
717
|
+
const result = await services.requestData(client, {
|
|
718
|
+
collection: 'users',
|
|
719
|
+
operation: 'getMany',
|
|
720
|
+
params: {},
|
|
721
|
+
timeout: 10000
|
|
722
|
+
});
|
|
723
|
+
```
|
|
724
|
+
|
|
725
|
+
### Event Unsubscription
|
|
726
|
+
|
|
727
|
+
All event handlers return an unsubscribe function:
|
|
728
|
+
|
|
729
|
+
```typescript
|
|
730
|
+
const unsubscribe = client.onMessage((message) => {
|
|
731
|
+
console.log('Message:', message);
|
|
732
|
+
});
|
|
733
|
+
|
|
734
|
+
// Later, when you want to stop listening
|
|
735
|
+
unsubscribe();
|
|
736
|
+
```
|
|
737
|
+
|
|
738
|
+
### Reconnection with Updated Config
|
|
739
|
+
|
|
740
|
+
You can reconnect with updated configuration without creating a new client:
|
|
741
|
+
|
|
742
|
+
```typescript
|
|
743
|
+
await client.reconnectWithConfig({
|
|
744
|
+
userId: 'new_user_id',
|
|
745
|
+
debug: true
|
|
746
|
+
});
|
|
747
|
+
```
|
|
748
|
+
|
|
749
|
+
## License
|
|
750
|
+
|
|
751
|
+
MIT
|
|
752
|
+
|
|
753
|
+
## Support
|
|
754
|
+
|
|
755
|
+
For issues and questions, please contact the SuperAtom team or refer to the SuperAtom platform documentation.
|