EdgeInteract
Acknowledgement
The acknowledgement stage completes the interaction cycle. After the server processes the response, it sends an InteractionAck back to the client. The client uses this to confirm the cycle is complete and dismiss the UI component cleanly.
InteractionAck Schema
| Field | Type | Description |
|---|---|---|
interactionId | string | The interaction that was completed |
status | "acknowledged" | "error" | Whether the server processed the response successfully |
processedAt | ISO 8601 | When the server finished processing |
errorMessage | string (optional) | Present only when status: "error" — human-readable error description |
Ack Topic
The InteractionAck is published on a per-interaction ack topic: interactions.ack.{interactionId}. The client subscribes to this topic as soon as it sends the response, and unsubscribes when the ack arrives.
Client Behavior on Ack
When the ack arrives with status: "acknowledged":
- The
respond()promise resolves — the calling component knows the cycle is complete - The interaction is marked as
acknowledgedin the local queue and moved to the history store - The UI component is unmounted (or hidden) — the user sees it disappear
- The callback topic subscription is cleaned up
When the ack arrives with status: "error":
- The
respond()promise rejects with anInteractionResponseError - The component should display the error and allow the user to retry
- The interaction remains in the queue (not dismissed) so the user can try again
Ack Timeout
The client waits up to 10 seconds for the ack after submitting a response. If no ack arrives within that window:
- The
respond()promise rejects with aInteractionAckTimeoutError - The interaction is left in an ambiguous state — the server may or may not have processed the response
- The UI should display a "response submitted, awaiting confirmation" state and allow the user to refresh
Idempotent Response Handling
Design your server-side response handlers to be idempotent. In rare cases (network issues, server restarts), the same response may be delivered more than once. Use the
interactionId as the idempotency key.
Full Ack Flow (Code)
// Inside InteractionResponsePublisher (simplified)
async function respond(
interaction: InteractionRequest,
outcome: string,
data?: unknown
): Promise<void> {
const response: InteractionResponse = {
interactionId: interaction.interactionId,
respondedBy: currentUser.id,
outcome,
data,
timestamp: new Date().toISOString(),
sessionId: edgeStreamSession.id
};
// Publish response to callback topic
await edgeStreamClient.publish(
`interactions.callback.${interaction.interactionId}`,
response
);
// Wait for server ack (with 10s timeout)
const ack = await edgeStreamClient.waitForMessage(
`interactions.ack.${interaction.interactionId}`,
{ timeoutMs: 10_000 }
);
if (ack.status === 'error') {
throw new InteractionResponseError(ack.errorMessage);
}
// Success — ack received
}