2025-06-30 18:58:24 +02:00
|
|
|
/*
|
|
|
|
SPDX-FileCopyrightText: © 2025 Hornwitser <code@hornwitser.no>
|
|
|
|
SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
*/
|
2025-03-05 16:02:26 +01:00
|
|
|
import { pipeline } from "node:stream";
|
2025-03-05 15:36:50 +01:00
|
|
|
import { addStream, deleteStream } from "~/server/streams";
|
2025-02-27 15:42:59 +01:00
|
|
|
|
2025-03-05 15:36:50 +01:00
|
|
|
export default defineEventHandler(async (event) => {
|
2025-06-09 16:51:05 +02:00
|
|
|
const session = await getServerSession(event);
|
2025-06-23 00:17:22 +02:00
|
|
|
const accountId = session?.account.id;
|
2025-03-10 16:26:52 +01:00
|
|
|
|
2025-02-27 15:42:59 +01:00
|
|
|
const encoder = new TextEncoder();
|
2025-03-05 15:36:50 +01:00
|
|
|
const source = event.headers.get("x-forwarded-for");
|
2025-02-27 15:42:59 +01:00
|
|
|
console.log(`starting event stream for ${source}`)
|
|
|
|
const stream = new TransformStream<string, Uint8Array>({
|
|
|
|
transform(chunk, controller) {
|
|
|
|
controller.enqueue(encoder.encode(chunk));
|
|
|
|
},
|
|
|
|
flush(controller) {
|
|
|
|
console.log(`finished event stream for ${source}`);
|
2025-02-27 18:39:04 +01:00
|
|
|
deleteStream(stream.writable);
|
2025-02-27 15:42:59 +01:00
|
|
|
},
|
|
|
|
// @ts-expect-error experimental API
|
|
|
|
cancel(reason) {
|
|
|
|
console.log(`cancelled event stream for ${source}`);
|
2025-02-27 18:39:04 +01:00
|
|
|
deleteStream(stream.writable);
|
2025-02-27 15:42:59 +01:00
|
|
|
}
|
|
|
|
})
|
2025-03-10 16:26:52 +01:00
|
|
|
addStream(stream.writable, session?.id, accountId);
|
2025-03-05 16:02:26 +01:00
|
|
|
|
|
|
|
// Workaround to properly handle stream errors. See https://github.com/unjs/h3/issues/986
|
|
|
|
setHeader(event, "Access-Control-Allow-Origin", "*");
|
|
|
|
setHeader(event, "Content-Type", "text/event-stream");
|
|
|
|
pipeline(stream.readable as unknown as NodeJS.ReadableStream, event.node.res, (err) => { /* ignore */ });
|
|
|
|
event._handled = true;
|
2025-03-05 15:36:50 +01:00
|
|
|
});
|