|
var __defProp = Object.defineProperty, __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: !0, configurable: !0, writable: !0, value }) : obj[key] = value, __publicField = (obj, key, value) => __defNormalProp(obj, typeof key != "symbol" ? key + "" : key, value); |
|
class ParseError extends Error { |
|
constructor(message, options) { |
|
super(message), __publicField(this, "type"), __publicField(this, "field"), __publicField(this, "value"), __publicField(this, "line"), this.name = "ParseError", this.type = options.type, this.field = options.field, this.value = options.value, this.line = options.line; |
|
} |
|
} |
|
function noop(_arg) { |
|
} |
|
function createParser(callbacks) { |
|
const { onEvent = noop, onError = noop, onRetry = noop, onComment } = callbacks; |
|
let incompleteLine = "", isFirstChunk = !0, id, data = "", eventType = ""; |
|
function feed(newChunk) { |
|
const chunk = isFirstChunk ? newChunk.replace(/^\xEF\xBB\xBF/, "") : newChunk, [complete, incomplete] = splitLines(`${incompleteLine}${chunk}`); |
|
for (const line of complete) |
|
parseLine(line); |
|
incompleteLine = incomplete, isFirstChunk = !1; |
|
} |
|
function parseLine(line) { |
|
if (line === "") { |
|
dispatchEvent(); |
|
return; |
|
} |
|
if (line.startsWith(":")) { |
|
onComment && onComment(line.slice(line.startsWith(": ") ? 2 : 1)); |
|
return; |
|
} |
|
const fieldSeparatorIndex = line.indexOf(":"); |
|
if (fieldSeparatorIndex !== -1) { |
|
const field = line.slice(0, fieldSeparatorIndex), offset = line[fieldSeparatorIndex + 1] === " " ? 2 : 1, value = line.slice(fieldSeparatorIndex + offset); |
|
processField(field, value, line); |
|
return; |
|
} |
|
processField(line, "", line); |
|
} |
|
function processField(field, value, line) { |
|
switch (field) { |
|
case "event": |
|
eventType = value; |
|
break; |
|
case "data": |
|
data = `${data}${value} |
|
`; |
|
break; |
|
case "id": |
|
id = value.includes("\0") ? void 0 : value; |
|
break; |
|
case "retry": |
|
/^\d+$/.test(value) ? onRetry(parseInt(value, 10)) : onError( |
|
new ParseError(`Invalid \`retry\` value: "${value}"`, { |
|
type: "invalid-retry", |
|
value, |
|
line |
|
}) |
|
); |
|
break; |
|
default: |
|
onError( |
|
new ParseError( |
|
`Unknown field "${field.length > 20 ? `${field.slice(0, 20)}\u2026` : field}"`, |
|
{ type: "unknown-field", field, value, line } |
|
) |
|
); |
|
break; |
|
} |
|
} |
|
function dispatchEvent() { |
|
data.length > 0 && onEvent({ |
|
id, |
|
event: eventType || void 0, |
|
|
|
|
|
data: data.endsWith(` |
|
`) ? data.slice(0, -1) : data |
|
}), id = void 0, data = "", eventType = ""; |
|
} |
|
function reset(options = {}) { |
|
incompleteLine && options.consume && parseLine(incompleteLine), id = void 0, data = "", eventType = "", incompleteLine = ""; |
|
} |
|
return { feed, reset }; |
|
} |
|
function splitLines(chunk) { |
|
const lines = []; |
|
let incompleteLine = ""; |
|
const totalLength = chunk.length; |
|
for (let i = 0; i < totalLength; i++) { |
|
const char = chunk[i]; |
|
char === "\r" && chunk[i + 1] === ` |
|
` ? (lines.push(incompleteLine), incompleteLine = "", i++) : char === "\r" || char === ` |
|
` ? (lines.push(incompleteLine), incompleteLine = "") : incompleteLine += char; |
|
} |
|
return [lines, incompleteLine]; |
|
} |
|
export { |
|
ParseError, |
|
createParser |
|
}; |
|
|
|
|