Add article history by SKU and SSE update signals for live clients.
Expose getHistoryBySku as GET /article/:sku/history, and document mutation-emitted company signals via GET /events.
This commit is contained in:
52
src/api/sse.js
Normal file
52
src/api/sse.js
Normal file
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* In-process SSE hub. Clients subscribe via GET /events; handlers call emit()
|
||||
* after a successful mutation so other tabs/users can refetch.
|
||||
*/
|
||||
|
||||
/** @typedef {{ res: import('express').Response, companyId: number, userId: number }} SseClient */
|
||||
|
||||
/** @type {Set<SseClient>} */
|
||||
const clients = new Set();
|
||||
|
||||
const KEEP_ALIVE_MS = 25_000;
|
||||
|
||||
/**
|
||||
* Register an open SSE response. Caller must write the initial headers.
|
||||
* @param {import('express').Response} res
|
||||
* @param {{ companyId: number, userId: number }} meta
|
||||
* @returns {() => void} unsubscribe
|
||||
*/
|
||||
export function subscribe(res, { companyId, userId }) {
|
||||
/** @type {SseClient} */
|
||||
const client = { res, companyId, userId };
|
||||
clients.add(client);
|
||||
|
||||
const keepAlive = setInterval(() => {
|
||||
if (res.writableEnded) return;
|
||||
res.write(': keepalive\n\n');
|
||||
}, KEEP_ALIVE_MS);
|
||||
|
||||
const unsubscribe = () => {
|
||||
clearInterval(keepAlive);
|
||||
clients.delete(client);
|
||||
};
|
||||
|
||||
res.on('close', unsubscribe);
|
||||
return unsubscribe;
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcast a named signal to subscribers of the given company.
|
||||
* @param {string} signal - SSE event name (e.g. `category`)
|
||||
* @param {{ companyId: number }} options
|
||||
*/
|
||||
export function emit(signal, { companyId }) {
|
||||
if (companyId == null) return;
|
||||
|
||||
const frame = `event: ${signal}\ndata: {}\n\n`;
|
||||
for (const client of clients) {
|
||||
if (client.companyId !== companyId) continue;
|
||||
if (client.res.writableEnded) continue;
|
||||
client.res.write(frame);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user