Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/abstractServerSentEventGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,16 @@ export abstract class ServerSentEventGenerator<T = string[]> {
);
}

/**
* Closes the server-sent event stream.
*
* Use this method to manually close the stream when `keepalive: true` is set.
* This is required when you want to close the stream before the client disconnects.
*
* Concrete implementations must override this method to close the underlying stream.
*/
public abstract close(): void;

private eachNewlineIsADataLine(prefix: string, data: string) {
return data.split("\n").map((line) => {
return `${prefix} ${line}`;
Expand Down
9 changes: 9 additions & 0 deletions src/node/serverSentEventGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,15 @@ export class ServerSentEventGenerator extends AbstractSSEGenerator {
return eventLines;
}

/**
* Closes the server-sent event stream.
*
* Ends the Node.js response stream.
*/
public override close(): void {
this.res.end();
}

/**
* Reads client sent signals based on HTTP methods
*
Expand Down
25 changes: 25 additions & 0 deletions src/web/serverSentEventGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,31 @@ export class ServerSentEventGenerator extends AbstractSSEGenerator {
return eventLines;
}

/**
* Closes the server-sent event stream.
*
* Closes the ReadableStream controller.
*/
public override close(): void {
if (!this.controller) {
return;
}

try {
this.controller.close();
} catch (err) {
// ReadableStream controllers throw when already closed.
// We only ignore TypeError (which indicates the stream is already closed).
// Other errors should bubble up as they indicate real problems.
if (err instanceof TypeError) {
// Stream is already closed, which is fine - ignore
return;
}
// Re-throw unexpected errors
throw err;
}
}

/**
* Reads client sent signals based on HTTP methods
*
Expand Down
Loading