@loaders.gl/json
Version:
Framework-independent loader for JSON and streaming JSON formats
99 lines • 3.24 kB
JavaScript
// loaders.gl
// SPDX-License-Identifier: MIT
// Copyright (c) vis.gl contributors
import { default as JSONParser } from "./json-parser.js";
import JSONPath from "../jsonpath/jsonpath.js";
/**
* The `StreamingJSONParser` looks for the first array in the JSON structure.
* and emits an array of chunks
*/
export default class StreamingJSONParser extends JSONParser {
jsonPaths;
streamingJsonPath = null;
streamingArray = null;
topLevelObject = null;
constructor(options = {}) {
super({
onopenarray: () => {
if (!this.streamingArray) {
if (this._matchJSONPath()) {
// @ts-ignore
this.streamingJsonPath = this.getJsonPath().clone();
this.streamingArray = [];
this._openArray(this.streamingArray);
return;
}
}
this._openArray();
},
// Redefine onopenarray to inject value for top-level object
onopenobject: (name) => {
if (!this.topLevelObject) {
this.topLevelObject = {};
this._openObject(this.topLevelObject);
}
else {
this._openObject({});
}
if (typeof name !== 'undefined') {
this.parser.emit('onkey', name);
}
}
});
const jsonpaths = options.jsonpaths || [];
this.jsonPaths = jsonpaths.map((jsonpath) => new JSONPath(jsonpath));
}
/**
* write REDEFINITION
* - super.write() chunk to parser
* - get the contents (so far) of "topmost-level" array as batch of rows
* - clear top-level array
* - return the batch of rows\
*/
write(chunk) {
super.write(chunk);
let array = [];
if (this.streamingArray) {
array = [...this.streamingArray];
this.streamingArray.length = 0;
}
return array;
}
/**
* Returns a partially formed result object
* Useful for returning the "wrapper" object when array is not top level
* e.g. GeoJSON
*/
getPartialResult() {
return this.topLevelObject;
}
getStreamingJsonPath() {
return this.streamingJsonPath;
}
getStreamingJsonPathAsString() {
return this.streamingJsonPath && this.streamingJsonPath.toString();
}
getJsonPath() {
return this.jsonpath;
}
// PRIVATE METHODS
/**
* Checks is this.getJsonPath matches the jsonpaths provided in options
*/
_matchJSONPath() {
const currentPath = this.getJsonPath();
// console.debug(`Testing JSONPath`, currentPath);
// Backwards compatibility, match any array
// TODO implement using wildcard once that is supported
if (this.jsonPaths.length === 0) {
return true;
}
for (const jsonPath of this.jsonPaths) {
if (jsonPath.equals(currentPath)) {
return true;
}
}
return false;
}
}
//# sourceMappingURL=streaming-json-parser.js.map