frontend app: deno vite svelte tailwind daisyui
This commit is contained in:
parent
4527ed19cc
commit
8e8872b2d2
18 changed files with 1119 additions and 0 deletions
86
chatsbt/src/lib/chatStore.svelte.js
Normal file
86
chatsbt/src/lib/chatStore.svelte.js
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
// Pure vanilla JS – no Svelte imports
|
||||
const BASE = import.meta.env.VITE_API_URL ?? 'http://localhost:8000';
|
||||
|
||||
export const chatStore = (() => {
|
||||
let chatId = $state(null); // null until first message
|
||||
let messages = $state([]);
|
||||
let input = $state('');
|
||||
let loading = $state(false);
|
||||
|
||||
/* ── helpers ── */
|
||||
async function createChat() {
|
||||
const res = await fetch(`${BASE}/chats`, { method: 'POST' });
|
||||
const { id } = await res.json();
|
||||
return id;
|
||||
}
|
||||
|
||||
async function sendUserMessage(text) {
|
||||
await fetch(`${BASE}/chats/${chatId}/messages`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ message: text })
|
||||
});
|
||||
}
|
||||
|
||||
function streamAssistantReply() {
|
||||
const source = new EventSource(`${BASE}/chats/${chatId}/stream`);
|
||||
let botMsg = { id: Date.now(), text: '', me: false, sender: 'bot' };
|
||||
messages = [...messages, botMsg];
|
||||
|
||||
source.onmessage = (ev) => {
|
||||
console.log(ev.data);
|
||||
if (ev.data === '[DONE]') {
|
||||
source.close();
|
||||
loading = false;
|
||||
return;
|
||||
}
|
||||
|
||||
messages = messages.map((m, i) =>
|
||||
i === messages.length - 1 ? { ...m, text: m.text + ev.data } : m
|
||||
);
|
||||
};
|
||||
|
||||
source.onerror = () => {
|
||||
source.close();
|
||||
loading = false;
|
||||
};
|
||||
}
|
||||
|
||||
async function send() {
|
||||
const text = input.trim();
|
||||
if (!text || loading) return;
|
||||
|
||||
// add user bubble immediately
|
||||
messages = [...messages, { id: Date.now(), text, me: true, sender: 'user' }];
|
||||
input = '';
|
||||
loading = true;
|
||||
|
||||
try {
|
||||
if (!chatId) chatId = await createChat();
|
||||
await sendUserMessage(text);
|
||||
streamAssistantReply();
|
||||
} catch {
|
||||
messages = [
|
||||
...messages,
|
||||
{ id: Date.now(), text: 'Sorry, something went wrong.', me: false, sender: 'bot' }
|
||||
];
|
||||
loading = false;
|
||||
}
|
||||
}
|
||||
|
||||
function handleKey(e) {
|
||||
if (e.key === 'Enter' && !e.shiftKey) {
|
||||
e.preventDefault();
|
||||
send();
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
get messages() { return messages; },
|
||||
get input() { return input; },
|
||||
set input(v) { input = v; },
|
||||
get loading() { return loading; },
|
||||
send,
|
||||
handleKey
|
||||
};
|
||||
})();
|
||||
Loading…
Add table
Add a link
Reference in a new issue