json-streaming-reader
Version:
Line delimited and concatenated JSON streaming protocol reader.
140 lines • 4.68 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var NAMES;
(function (NAMES) {
NAMES["START_OBJECT"] = "startObject";
NAMES["END_OBJECT"] = "endObject";
NAMES["START_ARRAY"] = "startArray";
NAMES["END_ARRAY"] = "endArray";
NAMES["KEY_VALUE"] = "keyValue";
NAMES["STRING_VALUE"] = "stringValue";
NAMES["NUMBER_VALUE"] = "numberValue";
NAMES["NULL_VALUE"] = "nullValue";
NAMES["TRUE_VALUE"] = "trueValue";
NAMES["FALSE_VALUE"] = "falseValue";
})(NAMES || (NAMES = {}));
class JsonStreamRecordBuilder {
constructor() {
this.done = false;
this.isArray = false;
this.isObject = false;
}
/**
* Purge builder to start accepting new record
*/
purge() {
this.record = undefined;
this.done = false;
this.isArray = false;
this.isObject = false;
this.childFieldKey = undefined;
this.childFieldValueBuilder = undefined;
}
/**
* Handle data chunk
* @param data
*/
onData(data) {
if (JsonStreamRecordBuilder.SUPPORTED_NAMES.indexOf(data.name) < 0) {
throw new Error(`Unable to process JSON chunk data ${JSON.stringify(data)}. Unsupported name.`);
}
if (this.done) {
throw new Error(`Unable to process JSON chunk data ${JSON.stringify(data)}. Record is already parsed.`);
}
if (this.childFieldValueBuilder) {
this.childFieldValueBuilder.onData(data);
if (this.childFieldValueBuilder.isDone()) {
if (this.isArray) {
this.record.push(this.childFieldValueBuilder.getRecord());
}
if (this.isObject) {
if (!this.childFieldKey) {
throw new Error(`Unable to process JSON chunk data ${JSON.stringify(data)}. Child field key not registered.`);
}
this.record[this.childFieldKey] = this.childFieldValueBuilder.getRecord();
}
this.childFieldValueBuilder = undefined;
this.childFieldKey = undefined;
}
return;
}
if (data.name === NAMES.START_OBJECT) {
if (!this.record) {
this.isObject = true;
this.record = {};
}
else {
this.childFieldValueBuilder = new JsonStreamRecordBuilder();
this.childFieldValueBuilder.onData(data);
}
return;
}
if (data.name === NAMES.START_ARRAY) {
if (!this.record) {
this.isArray = true;
this.record = [];
}
else {
this.childFieldValueBuilder = new JsonStreamRecordBuilder();
this.childFieldValueBuilder.onData(data);
}
return;
}
if (JsonStreamRecordBuilder.END_OBJECT_ARRAY_NAMES.indexOf(data.name) >= 0) {
this.done = true;
return;
}
if (data.name === NAMES.KEY_VALUE) {
this.childFieldKey = data.value;
return;
}
/* istanbul ignore else */
if (JsonStreamRecordBuilder.VALUE_NAMES.indexOf(data.name) >= 0) {
if (data.name === NAMES.NUMBER_VALUE) {
data.value = Number(data.value);
}
if (this.isArray) {
this.record.push(data.value);
return;
}
if (this.isObject) {
if (!this.childFieldKey) {
throw new Error(`Unable to process JSON chunk data ${JSON.stringify(data)}. Unable to assign value for missing key.`);
}
this.record[this.childFieldKey] = data.value;
this.childFieldKey = undefined;
return;
}
this.record = data.value;
this.done = true;
return;
}
}
/**
* Check if record construction is done
*/
isDone() {
return this.done;
}
/**
* Get constructed record
*/
getRecord() {
return this.record;
}
}
JsonStreamRecordBuilder.SUPPORTED_NAMES = Object.keys(NAMES)
.map(name => NAMES[name]);
JsonStreamRecordBuilder.END_OBJECT_ARRAY_NAMES = [
NAMES.END_OBJECT,
NAMES.END_ARRAY
];
JsonStreamRecordBuilder.VALUE_NAMES = [
NAMES.STRING_VALUE,
NAMES.NUMBER_VALUE,
NAMES.NULL_VALUE,
NAMES.TRUE_VALUE,
NAMES.FALSE_VALUE
];
exports.JsonStreamRecordBuilder = JsonStreamRecordBuilder;
//# sourceMappingURL=JsonStreamRecordBuilder.js.map