@dremio/js-sdk 0.45.3 → 0.45.4
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 +57 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -510,6 +510,63 @@ type ChatEventWithChunkType<T extends ChatEvent["content"]["chunkType"]> =
|
|
|
510
510
|
Extract<ChatEvent, { content: { chunkType: T } }>;
|
|
511
511
|
```
|
|
512
512
|
|
|
513
|
+
#### UI Rendering and React Reconciliation
|
|
514
|
+
|
|
515
|
+
The conversation snapshot produced by the reducer (and automatically managed by the `AgentConversationMachine`) is designed specifically for modern declarative UIs like React, Vue, Svelte, or Ink.
|
|
516
|
+
|
|
517
|
+
**You do not need to manually track message IDs, buffer stream chunks, or manage parallel tool call states.**
|
|
518
|
+
|
|
519
|
+
The reducer performs highly optimized, **immutable updates** as new events arrive. Because the top-level references change only when the underlying data changes, you can directly map over the snapshot in your render function. It is safe to pass these objects into memoized components (e.g., `React.memo`) without writing complex deep-equality checks or manual diffing logic.
|
|
520
|
+
|
|
521
|
+
**React Example:**
|
|
522
|
+
|
|
523
|
+
```typescript
|
|
524
|
+
import { createActor } from "xstate";
|
|
525
|
+
import { UserChatMessage } from "@dremio/js-sdk/enterprise/ai";
|
|
526
|
+
|
|
527
|
+
const actor = createActor(conversationMachine, {
|
|
528
|
+
input: { conversationId: null },
|
|
529
|
+
});
|
|
530
|
+
|
|
531
|
+
// Subscribe to state changes and update React state
|
|
532
|
+
actor.subscribe((snapshot) => {
|
|
533
|
+
setExchanges(snapshot.context.conversationSnapshot ?? []);
|
|
534
|
+
});
|
|
535
|
+
|
|
536
|
+
actor.start();
|
|
537
|
+
|
|
538
|
+
// In your render function - direct mapping, no manual diffing needed
|
|
539
|
+
return (
|
|
540
|
+
<div>
|
|
541
|
+
{exchanges.map((exchange) => (
|
|
542
|
+
<Exchange key={exchange.id} exchange={exchange} />
|
|
543
|
+
))}
|
|
544
|
+
</div>
|
|
545
|
+
);
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
**Why this works:**
|
|
549
|
+
|
|
550
|
+
- The reducer uses **structural sharing** via the `mutative` library, creating new object references only for changed data
|
|
551
|
+
- Unchanged exchanges and messages retain their original references, enabling efficient React reconciliation
|
|
552
|
+
- Maps preserve insertion order and provide O(1) lookups by ID
|
|
553
|
+
- Tool calls are automatically paired and their state is derived, eliminating manual tracking logic
|
|
554
|
+
|
|
555
|
+
**Vue/Svelte Example:**
|
|
556
|
+
|
|
557
|
+
```typescript
|
|
558
|
+
// The same principle applies - just bind to the snapshot
|
|
559
|
+
actor.subscribe((snapshot) => {
|
|
560
|
+
conversationSnapshot = snapshot.context.conversationSnapshot ?? [];
|
|
561
|
+
});
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
```svelte
|
|
565
|
+
{#each conversationSnapshot as exchange (exchange.id)}
|
|
566
|
+
<Exchange {exchange} />
|
|
567
|
+
{/each}
|
|
568
|
+
```
|
|
569
|
+
|
|
513
570
|
#### Incremental Updates
|
|
514
571
|
|
|
515
572
|
The reducer is a pure function with signature `(snapshot, events) => newSnapshot`. You can incrementally update a snapshot as new events arrive:
|