SnowLuma v2.4.2 source snapshot
Dev Build / cleanup (push) Waiting to run
Dev Build / typecheck (push) Waiting to run
Publish MCP to npm / Build, test, and publish MCP (push) Waiting to run
Publish SDK to npm / Build, test, and publish SDK (push) Waiting to run
Sync action catalog to docs / sync (push) Waiting to run
Publish UI to npm / Build and publish UI (push) Waiting to run
Build and Release / preflight (push) Waiting to run

This commit is contained in:
TanTan committed 2026-11-13 09:02:00 +08:00
commit fa9c73363d
1367 files changed
+355735

No files matched your search

+143
View File
@@ -0,0 +1,143 @@
import { afterEach, describe, it, expect, vi } from 'vitest';
import { sseResponse } from '../src/webui/sse-response';
describe('sseResponse', () => {
afterEach(() => {
vi.clearAllTimers();
vi.useRealTimers();
});
it('releases subscriptions immediately when the response body is canceled', async () => {
vi.useFakeTimers();
const request = new AbortController();
const cleanup = vi.fn();
let channel!: Parameters<Parameters<typeof sseResponse>[1]>[0];
const response = sseResponse(request.signal, (ch) => {
channel = ch;
ch.onClose(cleanup);
});
await response.body!.cancel();
expect(channel.isClosed()).toBe(true);
expect(cleanup).toHaveBeenCalledOnce();
expect(vi.getTimerCount()).toBe(0);
request.abort();
expect(cleanup).toHaveBeenCalledOnce();
});
it('does not subscribe when the request was already aborted', () => {
vi.useFakeTimers();
const request = new AbortController();
request.abort();
const start = vi.fn();
sseResponse(request.signal, start);
expect(start).not.toHaveBeenCalled();
expect(vi.getTimerCount()).toBe(0);
});
it('releases subscriptions registered before and after an abort during setup', () => {
vi.useFakeTimers();
const request = new AbortController();
const before = vi.fn();
const after = vi.fn();
sseResponse(request.signal, (channel) => {
channel.onClose(before);
request.abort();
channel.onClose(after);
});
expect(before).toHaveBeenCalledOnce();
expect(after).toHaveBeenCalledOnce();
expect(vi.getTimerCount()).toBe(0);
});
it('releases subscriptions when endpoint setup throws', () => {
vi.useFakeTimers();
const request = new AbortController();
const cleanup = vi.fn();
expect(() =>
sseResponse(request.signal, (channel) => {
channel.onClose(cleanup);
throw new Error('setup failed');
}),
).toThrow('setup failed');
expect(cleanup).toHaveBeenCalledOnce();
expect(vi.getTimerCount()).toBe(0);
});
it('finishes active streams and releases subscriptions during server shutdown', async () => {
const request = new AbortController();
const shutdown = new AbortController();
let cleanups = 0;
const response = sseResponse(
request.signal,
(channel) => {
channel.onClose(() => {
cleanups++;
});
},
shutdown.signal,
);
const reader = response.body!.getReader();
shutdown.abort();
expect(await reader.read()).toEqual({ done: true, value: undefined });
request.abort();
expect(cleanups).toBe(1);
});
it('returns an event-stream Response with the SSE headers', () => {
const ac = new AbortController();
const res = sseResponse(ac.signal, () => {
/* no-op */
});
expect(res.headers.get('Content-Type')).toBe('text/event-stream');
expect(res.headers.get('Cache-Control')).toBe('no-cache');
expect(res.headers.get('Connection')).toBe('keep-alive');
ac.abort(); // clear the heartbeat timer
});
it('ch.send frames JSON as `data: …` and ch.raw enqueues verbatim', async () => {
const ac = new AbortController();
const res = sseResponse(ac.signal, (ch) => {
ch.send({ type: 'ready' });
ch.raw(ch.encode(': heartbeat\n\n'));
});
const reader = res.body!.getReader();
const dec = new TextDecoder();
expect(dec.decode((await reader.read()).value)).toBe('data: {"type":"ready"}\n\n');
expect(dec.decode((await reader.read()).value)).toBe(': heartbeat\n\n');
ac.abort();
await reader.cancel();
});
it('abort runs registered cleanups exactly once, flips isClosed, and closes the stream', async () => {
const ac = new AbortController();
const cleanupA = vi.fn();
const cleanupB = vi.fn();
let channel!: Parameters<Parameters<typeof sseResponse>[1]>[0];
const res = sseResponse(ac.signal, (ch) => {
channel = ch;
ch.onClose(cleanupA);
ch.onClose(cleanupB);
});
expect(channel.isClosed()).toBe(false);
ac.abort();
expect(cleanupA).toHaveBeenCalledTimes(1);
expect(cleanupB).toHaveBeenCalledTimes(1);
expect(channel.isClosed()).toBe(true);
const r = await res.body!.getReader().read();
expect(r.done).toBe(true);
});
it('send after teardown is a silent no-op', () => {
const ac = new AbortController();
let channel!: Parameters<Parameters<typeof sseResponse>[1]>[0];
sseResponse(ac.signal, (ch) => {
channel = ch;
});
ac.abort();
expect(() => channel.send({ x: 1 })).not.toThrow();
expect(channel.isClosed()).toBe(true);
});
});