u
This commit is contained in:
@@ -53,6 +53,8 @@ function createCache(label, load) {
|
|||||||
|
|
||||||
class StorageManager {
|
class StorageManager {
|
||||||
#baseUrl;
|
#baseUrl;
|
||||||
|
/** @type {EventSource | null} */
|
||||||
|
#events = null;
|
||||||
|
|
||||||
constructor(baseUrl = window.location.origin) {
|
constructor(baseUrl = window.location.origin) {
|
||||||
this.#baseUrl = baseUrl;
|
this.#baseUrl = baseUrl;
|
||||||
@@ -233,19 +235,63 @@ class StorageManager {
|
|||||||
|
|
||||||
posterminalPromise: { get: () => posterminalCache.promise },
|
posterminalPromise: { get: () => posterminalCache.promise },
|
||||||
updatePosterminal: { value: posterminalCache.update },
|
updatePosterminal: { value: posterminalCache.update },
|
||||||
|
|
||||||
|
/** Close and reopen GET /api/events (required after selected-company change). */
|
||||||
|
reconnectEvents: { value: () => this.#reconnectEvents() },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET /api/events — SSE signals for the selected company.
|
||||||
|
* Stream is bound at connect time; reconnect after company switch.
|
||||||
|
*/
|
||||||
|
#reconnectEvents() {
|
||||||
|
this.#disconnectEvents();
|
||||||
|
const url = buildUrl(this.#baseUrl, '/api/events');
|
||||||
|
const es = new EventSource(url, { withCredentials: true });
|
||||||
|
es.addEventListener('category', () => {
|
||||||
|
void this.updateCategoryTree().catch((err) => {
|
||||||
|
console.error('[storageMgr] category event refresh failed', err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
es.addEventListener('articles', () => {
|
||||||
|
void this.updateArticleIndex().catch((err) => {
|
||||||
|
console.error('[storageMgr] articles event refresh failed', err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
es.onerror = () => {
|
||||||
|
console.error('[storageMgr] events stream error');
|
||||||
|
};
|
||||||
|
this.#events = es;
|
||||||
|
}
|
||||||
|
|
||||||
|
#disconnectEvents() {
|
||||||
|
if (!this.#events) return;
|
||||||
|
this.#events.close();
|
||||||
|
this.#events = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
#syncEvents(user) {
|
||||||
|
if (user?.selectedCompanyId != null) {
|
||||||
|
this.#reconnectEvents();
|
||||||
|
} else {
|
||||||
|
this.#disconnectEvents();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async #loadAuthMe() {
|
async #loadAuthMe() {
|
||||||
try {
|
try {
|
||||||
const data = await this.auth.me();
|
const data = await this.auth.me();
|
||||||
requireObject(data, 'GET /api/auth/me');
|
requireObject(data, 'GET /api/auth/me');
|
||||||
return {
|
const session = {
|
||||||
user: data.user,
|
user: data.user,
|
||||||
googleClientId: data.googleClientId,
|
googleClientId: data.googleClientId,
|
||||||
};
|
};
|
||||||
|
this.#syncEvents(session.user);
|
||||||
|
return session;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.status === 401 || err.status === 403) {
|
if (err.status === 401 || err.status === 403) {
|
||||||
|
this.#syncEvents(null);
|
||||||
return {
|
return {
|
||||||
user: null,
|
user: null,
|
||||||
googleClientId: err.data?.googleClientId,
|
googleClientId: err.data?.googleClientId,
|
||||||
|
|||||||
Reference in New Issue
Block a user