UNPKG

remix-nlux

Version:

Remix IDE NLUX integration. Remix IDE is the leading IDE for building and deploying smart contracts on Ethereum. NLUX is a JavaScript and React library for building conversational AI experiences.

55 lines (47 loc) 2.47 kB
import {useMemo} from 'react'; /** * In order to implement an optimized streaming experience, we cannot rely on React to manage the DOM elements * of the streaming messages. React UI is a function of state, and re-rendering the entire UI for every message * chunk would be inefficient. Instead, we use a service to manage the DOM elements of the streaming messages. * * This service creates a DOM element for each message ID and caches it. When a message ID is no longer needed, * the service deletes the DOM element. This way, we only have to update the DOM elements that are currently * visible on the screen. * * The NLUX stream renderer uses this service to obtain the DOM element for each message ID and will update them * in a very efficient way when new chunks are received. */ export type MarkdownContainersController = { getStreamingDomElement: (messageId: string) => HTMLDivElement; deleteStreamingDomElement: (messageId: string) => void; }; export const usMarkdownContainers: () => MarkdownContainersController = () => { const streamingDomElementsByMessageId: Record<string, HTMLDivElement> = {}; const victimMessageIds: Set<string> = new Set(); return useMemo<MarkdownContainersController>(() => ({ getStreamingDomElement: (messageId: string) => { if (victimMessageIds.has(messageId)) { victimMessageIds.delete(messageId); } if (streamingDomElementsByMessageId[messageId] === undefined) { const newStreamContainer = document.createElement('div'); newStreamContainer.setAttribute('nlux-message-id', messageId); newStreamContainer.className = 'nlux-markdown-container'; streamingDomElementsByMessageId[messageId] = newStreamContainer; } return streamingDomElementsByMessageId[messageId]; }, deleteStreamingDomElement: (messageId: string) => { victimMessageIds.add(messageId); setTimeout(() => { victimMessageIds.forEach((victimMessageId) => { if (streamingDomElementsByMessageId[victimMessageId]) { streamingDomElementsByMessageId[victimMessageId].remove(); delete streamingDomElementsByMessageId[victimMessageId]; } }); victimMessageIds.clear(); }, 1000); }, }), []); };