@superatomai/sdk-web 0.0.7 → 0.0.9

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 CHANGED
@@ -8,13 +8,14 @@ SuperAtom Web SDK - TypeScript SDK for browser-based WebSocket communication wit
8
8
  - 🔒 Type-safe message validation using Zod v4
9
9
  - 🎯 Request/response pattern with timeout support
10
10
  - 📦 Bundle management with chunked transfer
11
- - 🧩 Component registration system
11
+ - 🧩 Component registration and communication system
12
12
  - 🔐 Authentication (login and token verification)
13
13
  - 👥 User management (CRUD operations)
14
14
  - 📊 Dashboard management (CRUD operations)
15
15
  - 📈 Report management (CRUD operations)
16
- - 🤖 AI component suggestions
16
+ - 🤖 AI component suggestions with text streaming support
17
17
  - 💾 Data collection queries
18
+ - ⚡ Actions API for runtime operations
18
19
  - 📝 UI logging support
19
20
 
20
21
  ## Installation
@@ -127,21 +128,42 @@ const verifyResponse = await client.sendAuthVerifyRequest(
127
128
 
128
129
  ```typescript
129
130
  // Create a new user
130
- const result = await client.createUser(username, password, timeout);
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? }
131
140
 
132
141
  // Update an existing user
133
- const result = await client.updateUser(username, password, timeout);
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? }
134
153
 
135
154
  // Delete a user
136
155
  const result = await client.deleteUser(username, timeout);
156
+ // Returns: { success, username?, email?, fullname?, role?, message?, error? }
137
157
 
138
158
  // Get all users
139
159
  const result = await client.getAllUsers(timeout);
140
160
  // Returns: { success, users, count, error?, message? }
161
+ // User object: { username, email?, fullname?, role?, wsIds }
141
162
 
142
163
  // Get a specific user
143
164
  const result = await client.getUser(username, timeout);
144
165
  // Returns: { success, user, error?, message? }
166
+ // User object: { username, email?, fullname?, role?, wsIds }
145
167
  ```
146
168
 
147
169
  #### Dashboard Management
@@ -205,11 +227,25 @@ const result = await client.getReport(reportId, timeout);
205
227
  #### User Prompts & AI Suggestions
206
228
 
207
229
  ```typescript
208
- // Send a user prompt request
230
+ // Send a user prompt request (component mode - default)
209
231
  const response = await client.sendUserPromptRequest(
210
232
  prompt,
211
233
  threadId,
212
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
+ },
213
249
  timeout
214
250
  );
215
251
 
@@ -242,6 +278,36 @@ const result = await client.requestData({
242
278
  // Returns: { data?, error? }
243
279
  ```
244
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
+
245
311
  ### Component Setup
246
312
 
247
313
  Register your components with SuperAtom for dynamic rendering.
@@ -276,6 +342,7 @@ The SDK supports the following message types (all validated with Zod schemas):
276
342
 
277
343
  **User Prompts & AI**
278
344
  - `USER_PROMPT_REQ` / `USER_PROMPT_RES` - User prompt processing
345
+ - `USER_PROMPT_STREAM` - Real-time text streaming from AI responses
279
346
  - `USER_PROMPT_SUGGESTIONS_REQ` / `USER_PROMPT_SUGGESTIONS_RES` - Component suggestions
280
347
 
281
348
  **Bundle & Data**
@@ -287,11 +354,76 @@ The SDK supports the following message types (all validated with Zod schemas):
287
354
  - `DASHBOARDS` / `DASHBOARDS_RES` - Dashboard CRUD operations
288
355
  - `REPORTS` / `REPORTS_RES` - Report CRUD operations
289
356
 
357
+ **Actions & Components**
358
+ - `ACTIONS` / `ACTIONS_RES` - Runtime actions API
359
+ - `COMPONENT_LIST_RES` - Send component list to server
360
+
290
361
  **Logging**
291
362
  - `UI_LOGS` - UI logging messages
292
363
 
293
364
  All message types are fully typed and validated using Zod v4 schemas.
294
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
+
295
427
  ## Type Safety
296
428
 
297
429
  All messages are validated using Zod v4 schemas. The SDK exports comprehensive type definitions and schemas:
@@ -380,10 +512,19 @@ const client = new SuperatomClient({
380
512
 
381
513
  await client.connect();
382
514
 
383
- // Create a new user
384
- const createResult = await client.createUser('newuser', 'password123');
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
+ );
385
523
  if (createResult.success) {
386
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);
387
528
  }
388
529
 
389
530
  // Get all users
@@ -391,12 +532,25 @@ const usersResult = await client.getAllUsers();
391
532
  if (usersResult.success && usersResult.users) {
392
533
  console.log(`Found ${usersResult.count} users`);
393
534
  usersResult.users.forEach(user => {
394
- console.log(`- ${user.username} (${user.wsIds.length} connections)`);
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}`);
395
539
  });
396
540
  }
397
541
 
398
- // Update a user
399
- await client.updateUser('newuser', 'newpassword456');
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
+ });
400
554
 
401
555
  // Delete a user
402
556
  await client.deleteUser('newuser');
@@ -473,6 +627,81 @@ if (!result.error && result.data) {
473
627
  }
474
628
  ```
475
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
+
476
705
  ## Advanced Usage
477
706
 
478
707
  ### Direct Service Access
package/dist/index.cjs CHANGED
@@ -252,7 +252,8 @@ var UserPromptRequestPayloadSchema = zod.z.object({
252
252
  SA_RUNTIME: zod.z.object({
253
253
  threadId: zod.z.string(),
254
254
  uiBlockId: zod.z.string()
255
- }).optional()
255
+ }).optional(),
256
+ responseMode: zod.z.enum(["component", "text"]).optional()
256
257
  });
257
258
  var UserPromptRequestMessageSchema = zod.z.object({
258
259
  id: zod.z.string(),
@@ -434,7 +435,10 @@ var UsersRequestPayloadSchema = zod.z.object({
434
435
  operation: zod.z.enum(["create", "update", "delete", "getAll", "getOne"]),
435
436
  data: zod.z.object({
436
437
  username: zod.z.string().optional(),
437
- password: zod.z.string().optional()
438
+ email: zod.z.string().email("Invalid email format").optional(),
439
+ password: zod.z.string().optional(),
440
+ fullname: zod.z.string().optional(),
441
+ role: zod.z.string().optional()
438
442
  }).optional()
439
443
  });
440
444
  var UsersRequestMessageSchema = zod.z.object({
@@ -449,13 +453,22 @@ var UsersResponsePayloadSchema = zod.z.object({
449
453
  error: zod.z.string().optional(),
450
454
  data: zod.z.object({
451
455
  username: zod.z.string().optional(),
456
+ email: zod.z.string().optional(),
457
+ fullname: zod.z.string().optional(),
458
+ role: zod.z.string().optional(),
452
459
  message: zod.z.string().optional(),
453
460
  users: zod.z.array(zod.z.object({
454
461
  username: zod.z.string(),
462
+ email: zod.z.string().optional(),
463
+ fullname: zod.z.string().optional(),
464
+ role: zod.z.string().optional(),
455
465
  wsIds: zod.z.array(zod.z.string())
456
466
  })).optional(),
457
467
  user: zod.z.object({
458
468
  username: zod.z.string(),
469
+ email: zod.z.string().optional(),
470
+ fullname: zod.z.string().optional(),
471
+ role: zod.z.string().optional(),
459
472
  wsIds: zod.z.array(zod.z.string())
460
473
  }).optional(),
461
474
  count: zod.z.number().optional()
@@ -626,8 +639,8 @@ async function sendAuthVerifyRequest(client, token, timeout) {
626
639
  }
627
640
 
628
641
  // src/services/userPrompt.ts
629
- async function sendUserPromptRequest(client, prompt, threadId, uiBlockId, timeout) {
630
- const messageId = `msg_${Date.now()}`;
642
+ async function sendUserPromptRequest(client, prompt, threadId, uiBlockId, responseMode, onStream, timeout) {
643
+ const messageId = `user_prompt_req_msg_${Date.now()}`;
631
644
  const message = UserPromptRequestMessageSchema.parse({
632
645
  id: messageId,
633
646
  type: "USER_PROMPT_REQ",
@@ -642,11 +655,29 @@ async function sendUserPromptRequest(client, prompt, threadId, uiBlockId, timeou
642
655
  SA_RUNTIME: {
643
656
  threadId,
644
657
  uiBlockId
645
- }
658
+ },
659
+ responseMode
646
660
  }
647
661
  });
648
- const response = await client.sendWithResponse(message, timeout);
649
- return response;
662
+ let streamUnsubscribe = null;
663
+ if (responseMode === "text" && onStream) {
664
+ streamUnsubscribe = client.onMessage((msg) => {
665
+ if (msg.type === "USER_PROMPT_STREAM" && msg.id === `stream_${uiBlockId}`) {
666
+ const chunk = msg.payload?.chunk;
667
+ if (chunk) {
668
+ onStream(chunk);
669
+ }
670
+ }
671
+ });
672
+ }
673
+ try {
674
+ const response = await client.sendWithResponse(message, timeout);
675
+ return response;
676
+ } finally {
677
+ if (streamUnsubscribe) {
678
+ streamUnsubscribe();
679
+ }
680
+ }
650
681
  }
651
682
  async function sendUserPromptSuggestionsRequest(client, prompt, limit = 5, timeout) {
652
683
  if (!prompt || prompt.trim().length === 0) {
@@ -780,7 +811,7 @@ async function sendComponents(client, components) {
780
811
  }
781
812
 
782
813
  // src/services/users.ts
783
- async function createUser(client, username, password, timeout) {
814
+ async function createUser(client, username, password, email, fullname, role, timeout) {
784
815
  const messageId = `users_create_${Date.now()}`;
785
816
  const message = UsersRequestMessageSchema.parse({
786
817
  id: messageId,
@@ -791,7 +822,10 @@ async function createUser(client, username, password, timeout) {
791
822
  operation: "create",
792
823
  data: {
793
824
  username,
794
- password
825
+ password,
826
+ email,
827
+ fullname,
828
+ role
795
829
  }
796
830
  }
797
831
  });
@@ -801,10 +835,13 @@ async function createUser(client, username, password, timeout) {
801
835
  success: payload.success,
802
836
  error: payload.error,
803
837
  message: payload.data?.message,
804
- username: payload.data?.username
838
+ username: payload.data?.username,
839
+ email: payload.data?.email,
840
+ fullname: payload.data?.fullname,
841
+ role: payload.data?.role
805
842
  };
806
843
  }
807
- async function updateUser(client, username, password, timeout) {
844
+ async function updateUser(client, username, updates, timeout) {
808
845
  const messageId = `users_update_${Date.now()}`;
809
846
  const message = UsersRequestMessageSchema.parse({
810
847
  id: messageId,
@@ -815,7 +852,7 @@ async function updateUser(client, username, password, timeout) {
815
852
  operation: "update",
816
853
  data: {
817
854
  username,
818
- password
855
+ ...updates
819
856
  }
820
857
  }
821
858
  });
@@ -825,7 +862,10 @@ async function updateUser(client, username, password, timeout) {
825
862
  success: payload.success,
826
863
  error: payload.error,
827
864
  message: payload.data?.message,
828
- username: payload.data?.username
865
+ username: payload.data?.username,
866
+ email: payload.data?.email,
867
+ fullname: payload.data?.fullname,
868
+ role: payload.data?.role
829
869
  };
830
870
  }
831
871
  async function deleteUser(client, username, timeout) {
@@ -848,7 +888,10 @@ async function deleteUser(client, username, timeout) {
848
888
  success: payload.success,
849
889
  error: payload.error,
850
890
  message: payload.data?.message,
851
- username: payload.data?.username
891
+ username: payload.data?.username,
892
+ email: payload.data?.email,
893
+ fullname: payload.data?.fullname,
894
+ role: payload.data?.role
852
895
  };
853
896
  }
854
897
  async function getAllUsers(client, timeout) {
@@ -1441,10 +1484,12 @@ var SuperatomClient = class {
1441
1484
  /**
1442
1485
  * Send a user prompt request
1443
1486
  * Delegates to user prompt service
1487
+ * @param responseMode - 'component' for component response (default), 'text' for text streaming
1488
+ * @param onStream - Optional callback for streaming text chunks (only for text mode)
1444
1489
  */
1445
- async sendUserPromptRequest(prompt, threadId, uiBlockId, timeout) {
1446
- this.log("info", "Sending user prompt request");
1447
- return sendUserPromptRequest(this, prompt, threadId, uiBlockId, timeout);
1490
+ async sendUserPromptRequest(prompt, threadId, uiBlockId, responseMode, onStream, timeout) {
1491
+ this.log("info", "Sending user prompt request with streaming support");
1492
+ return sendUserPromptRequest(this, prompt, threadId, uiBlockId, responseMode, onStream, timeout);
1448
1493
  }
1449
1494
  /**
1450
1495
  * Send a user prompt suggestions request
@@ -1496,17 +1541,17 @@ var SuperatomClient = class {
1496
1541
  * Create a new user
1497
1542
  * Delegates to users service
1498
1543
  */
1499
- async createUser(username, password, timeout) {
1544
+ async createUser(username, password, email, fullname, role, timeout) {
1500
1545
  this.log("info", "Creating user:", username);
1501
- return createUser(this, username, password, timeout);
1546
+ return createUser(this, username, password, email, fullname, role, timeout);
1502
1547
  }
1503
1548
  /**
1504
1549
  * Update an existing user
1505
1550
  * Delegates to users service
1506
1551
  */
1507
- async updateUser(username, password, timeout) {
1552
+ async updateUser(username, updates, timeout) {
1508
1553
  this.log("info", "Updating user:", username);
1509
- return updateUser(this, username, password, timeout);
1554
+ return updateUser(this, username, updates, timeout);
1510
1555
  }
1511
1556
  /**
1512
1557
  * Delete a user