Display Stage
The display stage is where the EdgeStream message arrives in the browser and is transformed into a UI interaction. The InteractionSubscriber receives it, the InteractionContainer routes it, and the appropriate component renders.
Client-Side Reception Flow
EdgeStream Message Arrives
The EdgeStream client receives a message on the interactions.{userId} topic. The message is a serialized InteractionRequest JSON object.
InteractionSubscriber Handles It
InteractionSubscriber is already subscribed to this topic (set up by InteractionProvider on mount). It parses the JSON, validates the schema, and adds the interaction to the InteractionQueue.
InteractionQueue Notifies React
The queue notifies React state (via the InteractionContext). Components subscribed to the context re-render with the new interaction in the queue.
InteractionContainer Renders Component
InteractionContainer reads the type field from the first interaction in the queue, looks up the registered component for that type, and renders it with the typed payload and the respond() callback.
InteractionContainer Routing
The InteractionContainer maintains a registry of interaction type → component mappings. Built-in registrations:
| Type Key | Component | Package |
|---|---|---|
"approval" | ApprovalComponent | edge-interact-ui |
"confirmation" | ConfirmationComponent | edge-interact-ui |
"form" | FormComponent | edge-interact-ui |
"picker" | PickerComponent | edge-interact-ui |
"notification" | NotificationComponent | edge-interact-ui |
Custom types are registered with the registerInteractionRenderer function before rendering:
import { registerInteractionRenderer } from 'edge-interact-ui';
import { MyCustomComponent } from './MyCustomComponent';
// Register before the app renders
registerInteractionRenderer('my-company/special-review', MyCustomComponent);
Component Props Contract
Every component rendered by InteractionContainer receives this props interface:
interface InteractionComponentProps<TPayload = unknown> {
/** The full interaction request */
interaction: InteractionRequest<TPayload>;
/** Call this when the user has responded */
respond: (outcome: string, data?: unknown) => void;
/** Call this to cancel/dismiss without responding (e.g., "remind me later") */
dismiss?: () => void;
}
Interaction Queue
Multiple interactions can be in-flight simultaneously. The InteractionQueue manages them:
- Interactions are queued in arrival order, with
priority: "high"interactions inserted at the front - Only one interaction is displayed at a time (the front of the queue) — this prevents overwhelming the user
- After the user responds (or an interaction times out), the next in the queue is displayed automatically
- The queue is visible via
useInteractionContext().queue— useful for building an inbox view that shows all pending interactions
InteractionContainer's one-at-a-time display and render the full queue as a list (e.g., the WorkDesk HIL Inbox). Access the queue via useInteractionContext() and render each interaction yourself.
Display Notification to Server
When the InteractionSubscriber receives the message, it immediately sends a displayed acknowledgement to the server. This transitions the pipeline status from delivered to displayed and is used for response-time tracking (time from displayed to responded).
// This happens automatically inside InteractionSubscriber — for reference only
edgeStreamClient.publish('interactions.status', {
interactionId: interaction.interactionId,
status: 'displayed',
timestamp: new Date().toISOString()
});