From aced4a009fff72a16b389cf3bf82b9a24d89bcfd Mon Sep 17 00:00:00 2001 From: Ates Goral Date: Fri, 6 Oct 2023 16:31:38 -0400 Subject: [PATCH] Handle multi-line data while composing SSE --- src/server/event-stream.ts | 6 +++++- test/server/event-stream.test.ts | 14 ++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/server/event-stream.ts b/src/server/event-stream.ts index 34b3a49..454c1a0 100644 --- a/src/server/event-stream.ts +++ b/src/server/event-stream.ts @@ -39,7 +39,11 @@ export function eventStream( function send({ event = "message", data }: SendFunctionArgs) { controller.enqueue(encoder.encode(`event: ${event}\n`)); - controller.enqueue(encoder.encode(`data: ${data}\n\n`)); + + const lines = data.split("\n"); + const dataLines = lines.map((line) => `data: ${line}`).join("\n"); + + controller.enqueue(encoder.encode(`${dataLines}\n\n`)); } let cleanup = init(send, close); diff --git a/test/server/event-stream.test.ts b/test/server/event-stream.test.ts index 0a2b3ad..8537efe 100644 --- a/test/server/event-stream.test.ts +++ b/test/server/event-stream.test.ts @@ -28,6 +28,7 @@ describe(eventStream, () => { let controller = new AbortController(); let response = eventStream(controller.signal, (send, _) => { send({ data: "hello" }); + send({ event: "multi-line", data: "hello\nworld" }); return () => {}; }); @@ -36,12 +37,21 @@ describe(eventStream, () => { if (!response.body) throw new Error("Response body is undefined"); let reader = response.body.getReader(); + let decoder = new TextDecoder(); let { value: event } = await reader.read(); - expect(event).toEqual(new TextEncoder().encode("event: message\n")); + expect(decoder.decode(event)).toEqual("event: message\n"); let { value: data } = await reader.read(); - expect(data).toEqual(new TextEncoder().encode("data: hello\n\n")); + expect(decoder.decode(data)).toEqual("data: hello\n\n"); + + let { value: multiLineEvent } = await reader.read(); + expect(decoder.decode(multiLineEvent)).toEqual("event: multi-line\n"); + + let { value: multiLineData } = await reader.read(); + expect(decoder.decode(multiLineData)).toEqual( + "data: hello\ndata: world\n\n", + ); let { done } = await reader.read(); expect(done).toBe(true);