UNPKG

stream-chain

Version:

Chain functions, generators, Node streams, and Web streams into a pipeline with backpressure support.

72 lines (64 loc) 2.43 kB
// @ts-self-types="./parser.d.ts" import {none} from '../defs.js'; import gen from '../gen.js'; import fixUtf8Stream from '../utils/fixUtf8Stream.js'; import lines from '../utils/lines.js'; // Raw per-line parser factory — no `fixUtf8Stream()` / `lines()` front. Parallel // to the JSON tokenizer's `jsonParser` raw export; advanced callers compose the // input front themselves when chunks already arrive line-aligned. const jsonlParser = options => { const reviver = typeof options == 'function' ? options : options?.reviver; const hasErrorIndicator = !!options && 'errorIndicator' in options; let counter = 0; // `'errorIndicator' in options` is presence-check, so `errorIndicator: undefined` // is meaningful (drop bad lines); `errorIndicator: null` replaces them with null. // Wins over `ignoreErrors` when both are set. The indicator never changes, so the // function-form vs constant-form branch is picked once here, not per line. if (hasErrorIndicator) { const errorIndicator = options.errorIndicator; if (typeof errorIndicator == 'function') { // A function `errorIndicator` is invoked as `(error, input, reviver)`; its // return replaces the line (returning `undefined` drops it). return string => { if (!string) return none; let value; try { value = JSON.parse(string, reviver); } catch (error) { value = errorIndicator(error, string, reviver); } return value === undefined ? none : {key: counter++, value}; }; } // A non-function `errorIndicator` replaces the failed line as-is. return string => { if (!string) return none; let value; try { value = JSON.parse(string, reviver); } catch (_) { value = errorIndicator; } return value === undefined ? none : {key: counter++, value}; }; } if (options?.ignoreErrors) { return string => { if (!string) return none; try { return {key: counter++, value: JSON.parse(string, reviver)}; } catch (_) { return none; } }; } return string => { if (!string) return none; return {key: counter++, value: JSON.parse(string, reviver)}; }; }; const parser = options => gen(fixUtf8Stream(), lines(), jsonlParser(options)); parser.parser = parser; parser.jsonlParser = jsonlParser; export default parser; export {parser, jsonlParser};