File size: 2,224 Bytes
5f40163 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | import { create } from "zustand";
import { devtools } from "zustand/middleware";
import { v4 as uuidv4 } from "uuid";
export type BtwStatus = "pending" | "done" | "error";
export interface BtwEntry {
id: string;
question: string;
response?: string;
status: BtwStatus;
}
interface BtwState {
entriesByConversation: Record<string, BtwEntry[]>;
}
interface BtwActions {
addPending: (conversationId: string, question: string) => string;
resolve: (conversationId: string, id: string, response: string) => void;
fail: (conversationId: string, id: string, error: string) => void;
dismiss: (conversationId: string, id: string) => void;
}
type BtwStore = BtwState & BtwActions;
const initialState: BtwState = { entriesByConversation: {} };
const updateEntries = (
state: BtwState,
conversationId: string,
updater: (entries: BtwEntry[]) => BtwEntry[],
): Pick<BtwState, "entriesByConversation"> => ({
entriesByConversation: {
...state.entriesByConversation,
[conversationId]: updater(
state.entriesByConversation[conversationId] ?? [],
),
},
});
export const useBtwStore = create<BtwStore>()(
devtools(
(set) => ({
...initialState,
addPending: (conversationId, question) => {
const id = uuidv4();
set((s) =>
updateEntries(s, conversationId, (entries) => [
...entries,
{ id, question, status: "pending" },
]),
);
return id;
},
resolve: (conversationId, id, response) =>
set((s) =>
updateEntries(s, conversationId, (entries) =>
entries.map((e) =>
e.id === id ? { ...e, response, status: "done" } : e,
),
),
),
fail: (conversationId, id, error) =>
set((s) =>
updateEntries(s, conversationId, (entries) =>
entries.map((e) =>
e.id === id ? { ...e, response: error, status: "error" } : e,
),
),
),
dismiss: (conversationId, id) =>
set((s) =>
updateEntries(s, conversationId, (entries) =>
entries.filter((e) => e.id !== id),
),
),
}),
{ name: "BtwStore" },
),
);
|