Add browser security headers, implement upload temp directory management, and enhance SSE handling.
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
/** Reusable Server-Sent Events parser for browser and test environments. */
|
||||
export class SseParseError extends Error {
|
||||
constructor(message, details = {}) {
|
||||
super(message);
|
||||
this.name = "SseParseError";
|
||||
Object.assign(this, details);
|
||||
}
|
||||
}
|
||||
|
||||
function parseEvent(block, {onComment, onRetry} = {}) {
|
||||
if (!block) return null;
|
||||
let event = "message";
|
||||
const data = [];
|
||||
let id;
|
||||
let retry;
|
||||
for (const line of block.split(/\r?\n/)) {
|
||||
if (line.startsWith(":")) { onComment?.(line.slice(1).trimStart()); continue; }
|
||||
const separator = line.indexOf(":");
|
||||
const field = separator < 0 ? line : line.slice(0, separator);
|
||||
const value = separator < 0 ? "" : line.slice(separator + 1).replace(/^ /, "");
|
||||
if (field === "event") event = value;
|
||||
else if (field === "data") data.push(value);
|
||||
else if (field === "id" && !value.includes("\u0000")) id = value;
|
||||
else if (field === "retry" && /^\d+$/.test(value)) { retry = Number(value); onRetry?.(retry); }
|
||||
}
|
||||
if (!data.length) return null;
|
||||
return {event, data: data.join("\n"), ...(id !== undefined ? {id} : {}), ...(retry !== undefined ? {retry} : {})};
|
||||
}
|
||||
|
||||
export function createSseParser(options = {}) {
|
||||
let buffer = "";
|
||||
return {
|
||||
push(text) {
|
||||
buffer += text;
|
||||
const blocks = buffer.split(/\r?\n\r?\n/);
|
||||
buffer = blocks.pop() || "";
|
||||
return blocks.map(block => parseEvent(block, options)).filter(Boolean);
|
||||
},
|
||||
finish() {
|
||||
const event = parseEvent(buffer, options);
|
||||
buffer = "";
|
||||
return event ? [event] : [];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function parseSseData(event) {
|
||||
try { return JSON.parse(event.data); }
|
||||
catch (error) { throw new SseParseError("Malformed SSE JSON payload.", {cause: error, event}); }
|
||||
}
|
||||
Reference in New Issue
Block a user