167 lines
6.8 KiB
JavaScript
167 lines
6.8 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: !0 });
|
|
class ParseError extends Error {
|
|
constructor(message, options) {
|
|
super(message), this.name = "ParseError", this.type = options.type, this.field = options.field, this.value = options.value, this.line = options.line;
|
|
}
|
|
}
|
|
const LF = 10, CR = 13, SPACE = 32;
|
|
function noop(_arg) {
|
|
}
|
|
function createParser(callbacks) {
|
|
if (typeof callbacks == "function")
|
|
throw new TypeError(
|
|
"`callbacks` must be an object, got a function instead. Did you mean `{onEvent: fn}`?"
|
|
);
|
|
const { onEvent = noop, onError = noop, onRetry = noop, onComment } = callbacks, pendingFragments = [];
|
|
let isFirstChunk = !0, id, data = "", dataLines = 0, eventType;
|
|
function feed(chunk) {
|
|
if (isFirstChunk && (isFirstChunk = !1, chunk.charCodeAt(0) === 239 && chunk.charCodeAt(1) === 187 && chunk.charCodeAt(2) === 191 && (chunk = chunk.slice(3))), pendingFragments.length === 0) {
|
|
const trailing2 = processLines(chunk);
|
|
trailing2 !== "" && pendingFragments.push(trailing2);
|
|
return;
|
|
}
|
|
if (chunk.indexOf(`
|
|
`) === -1 && chunk.indexOf("\r") === -1) {
|
|
pendingFragments.push(chunk);
|
|
return;
|
|
}
|
|
pendingFragments.push(chunk);
|
|
const input = pendingFragments.join("");
|
|
pendingFragments.length = 0;
|
|
const trailing = processLines(input);
|
|
trailing !== "" && pendingFragments.push(trailing);
|
|
}
|
|
function processLines(chunk) {
|
|
let searchIndex = 0;
|
|
if (chunk.indexOf("\r") === -1) {
|
|
let lfIndex = chunk.indexOf(`
|
|
`, searchIndex);
|
|
for (; lfIndex !== -1; ) {
|
|
if (searchIndex === lfIndex) {
|
|
dataLines > 0 && onEvent({ id, event: eventType, data }), id = void 0, data = "", dataLines = 0, eventType = void 0, searchIndex = lfIndex + 1, lfIndex = chunk.indexOf(`
|
|
`, searchIndex);
|
|
continue;
|
|
}
|
|
const firstCharCode = chunk.charCodeAt(searchIndex);
|
|
if (isDataPrefix(chunk, searchIndex, firstCharCode)) {
|
|
const valueStart = chunk.charCodeAt(searchIndex + 5) === SPACE ? searchIndex + 6 : searchIndex + 5, value = chunk.slice(valueStart, lfIndex);
|
|
if (dataLines === 0 && chunk.charCodeAt(lfIndex + 1) === LF) {
|
|
onEvent({ id, event: eventType, data: value }), id = void 0, data = "", eventType = void 0, searchIndex = lfIndex + 2, lfIndex = chunk.indexOf(`
|
|
`, searchIndex);
|
|
continue;
|
|
}
|
|
data = dataLines === 0 ? value : `${data}
|
|
${value}`, dataLines++;
|
|
} else isEventPrefix(chunk, searchIndex, firstCharCode) ? eventType = chunk.slice(
|
|
chunk.charCodeAt(searchIndex + 6) === SPACE ? searchIndex + 7 : searchIndex + 6,
|
|
lfIndex
|
|
) || void 0 : parseLine(chunk, searchIndex, lfIndex);
|
|
searchIndex = lfIndex + 1, lfIndex = chunk.indexOf(`
|
|
`, searchIndex);
|
|
}
|
|
return chunk.slice(searchIndex);
|
|
}
|
|
for (; searchIndex < chunk.length; ) {
|
|
const crIndex = chunk.indexOf("\r", searchIndex), lfIndex = chunk.indexOf(`
|
|
`, searchIndex);
|
|
let lineEnd = -1;
|
|
if (crIndex !== -1 && lfIndex !== -1 ? lineEnd = crIndex < lfIndex ? crIndex : lfIndex : crIndex !== -1 ? crIndex === chunk.length - 1 ? lineEnd = -1 : lineEnd = crIndex : lfIndex !== -1 && (lineEnd = lfIndex), lineEnd === -1)
|
|
break;
|
|
parseLine(chunk, searchIndex, lineEnd), searchIndex = lineEnd + 1, chunk.charCodeAt(searchIndex - 1) === CR && chunk.charCodeAt(searchIndex) === LF && searchIndex++;
|
|
}
|
|
return chunk.slice(searchIndex);
|
|
}
|
|
function parseLine(chunk, start, end) {
|
|
if (start === end) {
|
|
dispatchEvent();
|
|
return;
|
|
}
|
|
const firstCharCode = chunk.charCodeAt(start);
|
|
if (isDataPrefix(chunk, start, firstCharCode)) {
|
|
const valueStart = chunk.charCodeAt(start + 5) === SPACE ? start + 6 : start + 5, value2 = chunk.slice(valueStart, end);
|
|
data = dataLines === 0 ? value2 : `${data}
|
|
${value2}`, dataLines++;
|
|
return;
|
|
}
|
|
if (isEventPrefix(chunk, start, firstCharCode)) {
|
|
eventType = chunk.slice(chunk.charCodeAt(start + 6) === SPACE ? start + 7 : start + 6, end) || void 0;
|
|
return;
|
|
}
|
|
if (firstCharCode === 105 && chunk.charCodeAt(start + 1) === 100 && chunk.charCodeAt(start + 2) === 58) {
|
|
const value2 = chunk.slice(chunk.charCodeAt(start + 3) === SPACE ? start + 4 : start + 3, end);
|
|
id = value2.includes("\0") ? void 0 : value2;
|
|
return;
|
|
}
|
|
if (firstCharCode === 58) {
|
|
if (onComment) {
|
|
const line2 = chunk.slice(start, end);
|
|
onComment(line2.slice(chunk.charCodeAt(start + 1) === SPACE ? 2 : 1));
|
|
}
|
|
return;
|
|
}
|
|
const line = chunk.slice(start, end), fieldSeparatorIndex = line.indexOf(":");
|
|
if (fieldSeparatorIndex === -1) {
|
|
processField(line, "", line);
|
|
return;
|
|
}
|
|
const field = line.slice(0, fieldSeparatorIndex), offset = line.charCodeAt(fieldSeparatorIndex + 1) === SPACE ? 2 : 1, value = line.slice(fieldSeparatorIndex + offset);
|
|
processField(field, value, line);
|
|
}
|
|
function processField(field, value, line) {
|
|
switch (field) {
|
|
case "event":
|
|
eventType = value || void 0;
|
|
break;
|
|
case "data":
|
|
data = dataLines === 0 ? value : `${data}
|
|
${value}`, dataLines++;
|
|
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() {
|
|
dataLines > 0 && onEvent({
|
|
id,
|
|
event: eventType,
|
|
data
|
|
}), id = void 0, data = "", dataLines = 0, eventType = void 0;
|
|
}
|
|
function reset(options = {}) {
|
|
if (options.consume && pendingFragments.length > 0) {
|
|
const incompleteLine = pendingFragments.join("");
|
|
parseLine(incompleteLine, 0, incompleteLine.length);
|
|
}
|
|
isFirstChunk = !0, id = void 0, data = "", dataLines = 0, eventType = void 0, pendingFragments.length = 0;
|
|
}
|
|
return { feed, reset };
|
|
}
|
|
function isDataPrefix(chunk, i, firstCharCode) {
|
|
return firstCharCode === 100 && chunk.charCodeAt(i + 1) === 97 && chunk.charCodeAt(i + 2) === 116 && chunk.charCodeAt(i + 3) === 97 && chunk.charCodeAt(i + 4) === 58;
|
|
}
|
|
function isEventPrefix(chunk, i, firstCharCode) {
|
|
return firstCharCode === 101 && chunk.charCodeAt(i + 1) === 118 && chunk.charCodeAt(i + 2) === 101 && chunk.charCodeAt(i + 3) === 110 && chunk.charCodeAt(i + 4) === 116 && chunk.charCodeAt(i + 5) === 58;
|
|
}
|
|
exports.ParseError = ParseError;
|
|
exports.createParser = createParser;
|
|
//# sourceMappingURL=index.cjs.map
|