@assistant-ui/react
Version:
TypeScript/React library for AI Chat
63 lines (51 loc) • 1.55 kB
text/typescript
import { useState, useCallback, useRef, useEffect } from "react";
import {
AssistantTransportCommand,
CommandQueueState,
QueuedCommand,
} from "./types";
export const createInitialQueueState = (): CommandQueueState => ({
queued: [],
inTransit: [],
});
export const useCommandQueue = (opts: { onQueue: () => void }) => {
const onQueueRef = useRef(opts.onQueue);
useEffect(() => {
onQueueRef.current = opts.onQueue;
});
const [, rerender] = useState(0);
const queueStateRef = useRef<CommandQueueState>(createInitialQueueState());
const enqueue = (command: AssistantTransportCommand) => {
queueStateRef.current = {
queued: [...queueStateRef.current.queued, command],
inTransit: queueStateRef.current.inTransit,
};
rerender((prev) => prev + 1);
onQueueRef.current();
};
const flush = (): QueuedCommand[] => {
if (queueStateRef.current.queued.length === 0) return [];
const queued = queueStateRef.current.queued;
queueStateRef.current = {
queued: [],
inTransit: [...queueStateRef.current.inTransit, ...queued],
};
rerender((prev) => prev + 1);
return queued;
};
const markDelivered = () => {
queueStateRef.current = { ...queueStateRef.current, inTransit: [] };
rerender((prev) => prev + 1);
};
const reset = useCallback(() => {
queueStateRef.current = createInitialQueueState();
rerender((prev) => prev + 1);
}, []);
return {
state: queueStateRef.current,
enqueue,
flush,
markDelivered,
reset,
};
};