This commit is contained in:
seb
2026-10-09 16:44:18 +02:00
parent 56274ecb1d
commit 5e62be468f
9 changed files with 175 additions and 71 deletions

View File

@@ -16,6 +16,7 @@
import { Automat } from 'react-automat';
import { modelconversation as modelconversationApi } from '../api';
import authAutomat from './authAutomat';
import { getSseClientId } from './sseAutomat';
import {
attachUserEnv,
getCurrentRoute,
@@ -110,6 +111,23 @@ let companyReconnectTimer = null;
let conversationStream = null;
let activeStreamConversationId = null;
/**
* Close the company-wide SSE stream (/api/events). Called on logout so no
* stale stream survives; reconnected on relogin via `ensureCompanyEventsConnected()`.
*/
function disconnectCompanyEvents() {
if (companyReconnectTimer) {
clearTimeout(companyReconnectTimer);
companyReconnectTimer = null;
}
if (companyEventSource) {
try {
companyEventSource.close();
} catch {}
companyEventSource = null;
}
}
/**
* Connect to company-wide SSE stream (/api/events) to listen for 'modelconversation' events.
*/
@@ -128,7 +146,10 @@ function ensureCompanyEventsConnected() {
companyReconnectTimer = null;
}
const es = new EventSource('/api/events', { withCredentials: true });
const url = new URL('/api/events', window.location.origin);
const cid = getSseClientId();
if (cid) url.searchParams.set('cid', cid);
const es = new EventSource(url.href, { withCredentials: true });
companyEventSource = es;
es.addEventListener('modelconversation', () => {
@@ -1362,28 +1383,24 @@ const actions = {
*/
reset() {
closeConversationStream();
if (companyEventSource) {
try {
companyEventSource.close();
} catch {}
companyEventSource = null;
}
if (companyReconnectTimer) {
clearTimeout(companyReconnectTimer);
companyReconnectTimer = null;
}
disconnectCompanyEvents();
chatAutomat.setState(initialState);
},
};
chatAutomat = new Automat(initialState, actions, { name: 'chat' });
// Listen to auth changes: reset on logout or company change
// Listen to auth changes: disconnect on logout, reconnect on relogin/company change.
let chatWasAuthed = false;
authAutomat.subscribe((auth) => {
const companyId = auth.user?.selectedCompanyId;
const isAuthed = auth.status === 'authed' && companyId != null;
const relogin = isAuthed && !chatWasAuthed;
chatWasAuthed = isAuthed;
if (auth.status === 'anon' || !companyId) {
disconnectCompanyEvents();
chatAutomat.actions.reset();
} else if (auth.status === 'authed' && companyId) {
} else if (relogin || (auth.status === 'authed' && companyId)) {
if (chatAutomat.state.sseEstablished) {
ensureCompanyEventsConnected();
void chatAutomat.actions.loadConversations(true);