Ny Editor-komponent med Tiptap (bold, italic, code, mentions). Chat og notater oppretter nå MENTIONS-edges i kunnskapsgrafen automatisk ved lagring. SpacetimeDB-adapter skriver alltid via PG API først for edge-atomisitet. RLS SET LOCAL fix i db.ts. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
60 lines
1.5 KiB
TypeScript
60 lines
1.5 KiB
TypeScript
import type { Message, ChatConnection, MentionRef } from './types';
|
|
|
|
/**
|
|
* Chat-adapter som poller PostgreSQL via REST API.
|
|
* Brukes som fallback når SpacetimeDB ikke er tilgjengelig,
|
|
* og som referanseimplementasjon for testing.
|
|
*/
|
|
export function createPgChat(channelId: string): ChatConnection {
|
|
let messages = $state<Message[]>([]);
|
|
let error = $state('');
|
|
let connected = $state(false);
|
|
let timer: ReturnType<typeof setInterval> | null = null;
|
|
let destroyed = false;
|
|
|
|
async function refresh() {
|
|
if (destroyed) return;
|
|
try {
|
|
const res = await fetch(`/api/channels/${channelId}/messages`);
|
|
if (!res.ok) throw new Error('Feil ved lasting');
|
|
messages = await res.json();
|
|
error = '';
|
|
connected = true;
|
|
} catch {
|
|
error = 'Kunne ikke laste meldinger';
|
|
connected = false;
|
|
}
|
|
}
|
|
|
|
async function send(body: string, mentions?: MentionRef[]) {
|
|
error = '';
|
|
try {
|
|
const res = await fetch(`/api/channels/${channelId}/messages`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ body, mentions })
|
|
});
|
|
if (!res.ok) throw new Error('Feil ved sending');
|
|
await refresh();
|
|
} catch {
|
|
error = 'Kunne ikke sende melding';
|
|
}
|
|
}
|
|
|
|
function destroy() {
|
|
destroyed = true;
|
|
if (timer) clearInterval(timer);
|
|
}
|
|
|
|
// Start polling
|
|
refresh();
|
|
timer = setInterval(refresh, 3000);
|
|
|
|
return {
|
|
get messages() { return messages; },
|
|
get error() { return error; },
|
|
get connected() { return connected; },
|
|
send,
|
|
destroy
|
|
};
|
|
}
|