@loaders.gl/json 4.2.0-alpha.3 → 4.2.0-alpha.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dist.dev.js +341 -409
- package/dist/dist.min.js +21 -0
- package/dist/geojson-loader.d.ts +1 -1
- package/dist/geojson-loader.d.ts.map +1 -1
- package/dist/geojson-loader.js +75 -73
- package/dist/geojson-worker.js +1 -1
- package/dist/geojson-writer.js +23 -20
- package/dist/index.cjs +120 -94
- package/dist/index.cjs.map +7 -0
- package/dist/index.d.ts +12 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/json-loader.js +30 -37
- package/dist/json-writer.js +14 -11
- package/dist/lib/clarinet/clarinet.js +511 -391
- package/dist/lib/encoder-utils/encode-table-row.d.ts +1 -1
- package/dist/lib/encoder-utils/encode-table-row.d.ts.map +1 -1
- package/dist/lib/encoder-utils/encode-table-row.js +46 -37
- package/dist/lib/encoder-utils/encode-utils.js +38 -25
- package/dist/lib/encoder-utils/utf8-encoder.js +25 -27
- package/dist/lib/encoders/geojson-encoder.d.ts +1 -1
- package/dist/lib/encoders/geojson-encoder.d.ts.map +1 -1
- package/dist/lib/encoders/geojson-encoder.js +43 -40
- package/dist/lib/encoders/json-encoder.d.ts +1 -1
- package/dist/lib/encoders/json-encoder.d.ts.map +1 -1
- package/dist/lib/encoders/json-encoder.js +17 -9
- package/dist/lib/json-parser/json-parser.d.ts +2 -2
- package/dist/lib/json-parser/json-parser.d.ts.map +1 -1
- package/dist/lib/json-parser/json-parser.js +85 -102
- package/dist/lib/json-parser/streaming-json-parser.d.ts +2 -2
- package/dist/lib/json-parser/streaming-json-parser.d.ts.map +1 -1
- package/dist/lib/json-parser/streaming-json-parser.js +86 -63
- package/dist/lib/jsonpath/jsonpath.js +77 -57
- package/dist/lib/parsers/parse-json-in-batches.d.ts +1 -1
- package/dist/lib/parsers/parse-json-in-batches.d.ts.map +1 -1
- package/dist/lib/parsers/parse-json-in-batches.js +76 -75
- package/dist/lib/parsers/parse-json.d.ts +1 -1
- package/dist/lib/parsers/parse-json.d.ts.map +1 -1
- package/dist/lib/parsers/parse-json.js +21 -22
- package/dist/lib/parsers/parse-ndjson-in-batches.js +26 -28
- package/dist/lib/parsers/parse-ndjson.js +10 -10
- package/dist/ndgeoson-loader.js +28 -20
- package/dist/ndjson-loader.js +22 -14
- package/dist/workers/geojson-worker.js +0 -1
- package/package.json +11 -7
- package/dist/geojson-loader.js.map +0 -1
- package/dist/geojson-writer.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/json-loader.js.map +0 -1
- package/dist/json-writer.js.map +0 -1
- package/dist/lib/clarinet/LICENSE +0 -28
- package/dist/lib/clarinet/clarinet.js.map +0 -1
- package/dist/lib/encoder-utils/encode-table-row.js.map +0 -1
- package/dist/lib/encoder-utils/encode-utils.js.map +0 -1
- package/dist/lib/encoder-utils/utf8-encoder.js.map +0 -1
- package/dist/lib/encoders/geojson-encoder.js.map +0 -1
- package/dist/lib/encoders/json-encoder.js.map +0 -1
- package/dist/lib/json-parser/json-parser.js.map +0 -1
- package/dist/lib/json-parser/streaming-json-parser.js.map +0 -1
- package/dist/lib/jsonpath/jsonpath.js.map +0 -1
- package/dist/lib/parsers/parse-json-in-batches.js.map +0 -1
- package/dist/lib/parsers/parse-json.js.map +0 -1
- package/dist/lib/parsers/parse-ndjson-in-batches.js.map +0 -1
- package/dist/lib/parsers/parse-ndjson.js.map +0 -1
- package/dist/ndgeoson-loader.js.map +0 -1
- package/dist/ndjson-loader.js.map +0 -1
- package/dist/workers/geojson-worker.js.map +0 -1
|
@@ -1,71 +1,94 @@
|
|
|
1
1
|
import { default as JSONParser } from "./json-parser.js";
|
|
2
2
|
import JSONPath from "../jsonpath/jsonpath.js";
|
|
3
|
+
/**
|
|
4
|
+
* The `StreamingJSONParser` looks for the first array in the JSON structure.
|
|
5
|
+
* and emits an array of chunks
|
|
6
|
+
*/
|
|
3
7
|
export default class StreamingJSONParser extends JSONParser {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
8
|
+
constructor(options = {}) {
|
|
9
|
+
super({
|
|
10
|
+
onopenarray: () => {
|
|
11
|
+
if (!this.streamingArray) {
|
|
12
|
+
if (this._matchJSONPath()) {
|
|
13
|
+
// @ts-ignore
|
|
14
|
+
this.streamingJsonPath = this.getJsonPath().clone();
|
|
15
|
+
this.streamingArray = [];
|
|
16
|
+
this._openArray(this.streamingArray);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
this._openArray();
|
|
21
|
+
},
|
|
22
|
+
// Redefine onopenarray to inject value for top-level object
|
|
23
|
+
onopenobject: (name) => {
|
|
24
|
+
if (!this.topLevelObject) {
|
|
25
|
+
this.topLevelObject = {};
|
|
26
|
+
this._openObject(this.topLevelObject);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
this._openObject({});
|
|
30
|
+
}
|
|
31
|
+
if (typeof name !== 'undefined') {
|
|
32
|
+
this.parser.emit('onkey', name);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
this.streamingJsonPath = null;
|
|
37
|
+
this.streamingArray = null;
|
|
38
|
+
this.topLevelObject = null;
|
|
39
|
+
const jsonpaths = options.jsonpaths || [];
|
|
40
|
+
this.jsonPaths = jsonpaths.map((jsonpath) => new JSONPath(jsonpath));
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* write REDEFINITION
|
|
44
|
+
* - super.write() chunk to parser
|
|
45
|
+
* - get the contents (so far) of "topmost-level" array as batch of rows
|
|
46
|
+
* - clear top-level array
|
|
47
|
+
* - return the batch of rows\
|
|
48
|
+
*/
|
|
49
|
+
write(chunk) {
|
|
50
|
+
super.write(chunk);
|
|
51
|
+
let array = [];
|
|
52
|
+
if (this.streamingArray) {
|
|
53
|
+
array = [...this.streamingArray];
|
|
54
|
+
this.streamingArray.length = 0;
|
|
27
55
|
}
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
write(chunk) {
|
|
38
|
-
super.write(chunk);
|
|
39
|
-
let array = [];
|
|
40
|
-
if (this.streamingArray) {
|
|
41
|
-
array = [...this.streamingArray];
|
|
42
|
-
this.streamingArray.length = 0;
|
|
56
|
+
return array;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Returns a partially formed result object
|
|
60
|
+
* Useful for returning the "wrapper" object when array is not top level
|
|
61
|
+
* e.g. GeoJSON
|
|
62
|
+
*/
|
|
63
|
+
getPartialResult() {
|
|
64
|
+
return this.topLevelObject;
|
|
43
65
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
getPartialResult() {
|
|
47
|
-
return this.topLevelObject;
|
|
48
|
-
}
|
|
49
|
-
getStreamingJsonPath() {
|
|
50
|
-
return this.streamingJsonPath;
|
|
51
|
-
}
|
|
52
|
-
getStreamingJsonPathAsString() {
|
|
53
|
-
return this.streamingJsonPath && this.streamingJsonPath.toString();
|
|
54
|
-
}
|
|
55
|
-
getJsonPath() {
|
|
56
|
-
return this.jsonpath;
|
|
57
|
-
}
|
|
58
|
-
_matchJSONPath() {
|
|
59
|
-
const currentPath = this.getJsonPath();
|
|
60
|
-
if (this.jsonPaths.length === 0) {
|
|
61
|
-
return true;
|
|
66
|
+
getStreamingJsonPath() {
|
|
67
|
+
return this.streamingJsonPath;
|
|
62
68
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
69
|
+
getStreamingJsonPathAsString() {
|
|
70
|
+
return this.streamingJsonPath && this.streamingJsonPath.toString();
|
|
71
|
+
}
|
|
72
|
+
getJsonPath() {
|
|
73
|
+
return this.jsonpath;
|
|
74
|
+
}
|
|
75
|
+
// PRIVATE METHODS
|
|
76
|
+
/**
|
|
77
|
+
* Checks is this.getJsonPath matches the jsonpaths provided in options
|
|
78
|
+
*/
|
|
79
|
+
_matchJSONPath() {
|
|
80
|
+
const currentPath = this.getJsonPath();
|
|
81
|
+
// console.debug(`Testing JSONPath`, currentPath);
|
|
82
|
+
// Backwards compatibility, match any array
|
|
83
|
+
// TODO implement using wildcard once that is supported
|
|
84
|
+
if (this.jsonPaths.length === 0) {
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
for (const jsonPath of this.jsonPaths) {
|
|
88
|
+
if (jsonPath.equals(currentPath)) {
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return false;
|
|
67
93
|
}
|
|
68
|
-
return false;
|
|
69
|
-
}
|
|
70
94
|
}
|
|
71
|
-
//# sourceMappingURL=streaming-json-parser.js.map
|
|
@@ -1,66 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A parser for a minimal subset of the jsonpath standard
|
|
3
|
+
* Full JSON path parsers for JS exist but are quite large (bundle size)
|
|
4
|
+
*
|
|
5
|
+
* Supports
|
|
6
|
+
*
|
|
7
|
+
* `$.component.component.component`
|
|
8
|
+
*/
|
|
1
9
|
export default class JSONPath {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
10
|
+
constructor(path = null) {
|
|
11
|
+
this.path = ['$'];
|
|
12
|
+
if (path instanceof JSONPath) {
|
|
13
|
+
// @ts-ignore
|
|
14
|
+
this.path = [...path.path];
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (Array.isArray(path)) {
|
|
18
|
+
this.path.push(...path);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
// Parse a string as a JSONPath
|
|
22
|
+
if (typeof path === 'string') {
|
|
23
|
+
this.path = path.split('.');
|
|
24
|
+
if (this.path[0] !== '$') {
|
|
25
|
+
throw new Error('JSONPaths must start with $');
|
|
26
|
+
}
|
|
27
|
+
}
|
|
9
28
|
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
return;
|
|
29
|
+
clone() {
|
|
30
|
+
return new JSONPath(this);
|
|
13
31
|
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
if (this.path[0] !== '$') {
|
|
17
|
-
throw new Error('JSONPaths must start with $');
|
|
18
|
-
}
|
|
32
|
+
toString() {
|
|
33
|
+
return this.path.join('.');
|
|
19
34
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
return new JSONPath(this);
|
|
23
|
-
}
|
|
24
|
-
toString() {
|
|
25
|
-
return this.path.join('.');
|
|
26
|
-
}
|
|
27
|
-
push(name) {
|
|
28
|
-
this.path.push(name);
|
|
29
|
-
}
|
|
30
|
-
pop() {
|
|
31
|
-
return this.path.pop();
|
|
32
|
-
}
|
|
33
|
-
set(name) {
|
|
34
|
-
this.path[this.path.length - 1] = name;
|
|
35
|
-
}
|
|
36
|
-
equals(other) {
|
|
37
|
-
if (!this || !other || this.path.length !== other.path.length) {
|
|
38
|
-
return false;
|
|
35
|
+
push(name) {
|
|
36
|
+
this.path.push(name);
|
|
39
37
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
return false;
|
|
43
|
-
}
|
|
38
|
+
pop() {
|
|
39
|
+
return this.path.pop();
|
|
44
40
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
setFieldAtPath(object, value) {
|
|
48
|
-
const path = [...this.path];
|
|
49
|
-
path.shift();
|
|
50
|
-
const field = path.pop();
|
|
51
|
-
for (const component of path) {
|
|
52
|
-
object = object[component];
|
|
41
|
+
set(name) {
|
|
42
|
+
this.path[this.path.length - 1] = name;
|
|
53
43
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
44
|
+
equals(other) {
|
|
45
|
+
if (!this || !other || this.path.length !== other.path.length) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
for (let i = 0; i < this.path.length; ++i) {
|
|
49
|
+
if (this.path[i] !== other.path[i]) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Sets the value pointed at by path
|
|
57
|
+
* TODO - handle root path
|
|
58
|
+
* @param object
|
|
59
|
+
* @param value
|
|
60
|
+
*/
|
|
61
|
+
setFieldAtPath(object, value) {
|
|
62
|
+
const path = [...this.path];
|
|
63
|
+
path.shift();
|
|
64
|
+
const field = path.pop();
|
|
65
|
+
for (const component of path) {
|
|
66
|
+
object = object[component];
|
|
67
|
+
}
|
|
68
|
+
// @ts-ignore
|
|
69
|
+
object[field] = value;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Gets the value pointed at by path
|
|
73
|
+
* TODO - handle root path
|
|
74
|
+
* @param object
|
|
75
|
+
*/
|
|
76
|
+
getFieldAtPath(object) {
|
|
77
|
+
const path = [...this.path];
|
|
78
|
+
path.shift();
|
|
79
|
+
const field = path.pop();
|
|
80
|
+
for (const component of path) {
|
|
81
|
+
object = object[component];
|
|
82
|
+
}
|
|
83
|
+
// @ts-ignore
|
|
84
|
+
return object[field];
|
|
62
85
|
}
|
|
63
|
-
return object[field];
|
|
64
|
-
}
|
|
65
86
|
}
|
|
66
|
-
//# sourceMappingURL=jsonpath.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { TableBatch } from '@loaders.gl/schema';
|
|
2
|
-
import type { JSONLoaderOptions, MetadataBatch, JSONBatch } from
|
|
2
|
+
import type { JSONLoaderOptions, MetadataBatch, JSONBatch } from "../../json-loader.js";
|
|
3
3
|
export declare function parseJSONInBatches(binaryAsyncIterator: AsyncIterable<ArrayBuffer> | Iterable<ArrayBuffer>, options: JSONLoaderOptions): AsyncIterable<TableBatch | MetadataBatch | JSONBatch>;
|
|
4
4
|
export declare function rebuildJsonObject(batch: any, data: any): any;
|
|
5
5
|
//# sourceMappingURL=parse-json-in-batches.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse-json-in-batches.d.ts","sourceRoot":"","sources":["../../../src/lib/parsers/parse-json-in-batches.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAS,UAAU,EAAC,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAC,iBAAiB,EAAE,aAAa,EAAE,SAAS,EAAC,
|
|
1
|
+
{"version":3,"file":"parse-json-in-batches.d.ts","sourceRoot":"","sources":["../../../src/lib/parsers/parse-json-in-batches.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAS,UAAU,EAAC,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAC,iBAAiB,EAAE,aAAa,EAAE,SAAS,EAAC,6BAA0B;AAQnF,wBAAuB,kBAAkB,CACvC,mBAAmB,EAAE,aAAa,CAAC,WAAW,CAAC,GAAG,QAAQ,CAAC,WAAW,CAAC,EACvE,OAAO,EAAE,iBAAiB,GACzB,aAAa,CAAC,UAAU,GAAG,aAAa,GAAG,SAAS,CAAC,CA2EvD;AAED,wBAAgB,iBAAiB,CAAC,KAAK,KAAA,EAAE,IAAI,KAAA,OAmB5C"}
|
|
@@ -2,86 +2,87 @@ import { TableBatchBuilder } from '@loaders.gl/schema';
|
|
|
2
2
|
import { assert, makeTextDecoderIterator } from '@loaders.gl/loader-utils';
|
|
3
3
|
import StreamingJSONParser from "../json-parser/streaming-json-parser.js";
|
|
4
4
|
import JSONPath from "../jsonpath/jsonpath.js";
|
|
5
|
+
// TODO - support batch size 0 = no batching/single batch?
|
|
6
|
+
// eslint-disable-next-line max-statements, complexity
|
|
5
7
|
export async function* parseJSONInBatches(binaryAsyncIterator, options) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
8
|
+
const asyncIterator = makeTextDecoderIterator(binaryAsyncIterator);
|
|
9
|
+
const { metadata } = options;
|
|
10
|
+
const { jsonpaths } = options.json || {};
|
|
11
|
+
let isFirstChunk = true;
|
|
12
|
+
// @ts-expect-error TODO fix Schema deduction
|
|
13
|
+
const schema = null;
|
|
14
|
+
const tableBatchBuilder = new TableBatchBuilder(schema, options);
|
|
15
|
+
const parser = new StreamingJSONParser({ jsonpaths });
|
|
16
|
+
for await (const chunk of asyncIterator) {
|
|
17
|
+
const rows = parser.write(chunk);
|
|
18
|
+
const jsonpath = rows.length > 0 && parser.getStreamingJsonPathAsString();
|
|
19
|
+
if (rows.length > 0 && isFirstChunk) {
|
|
20
|
+
if (metadata) {
|
|
21
|
+
const initialBatch = {
|
|
22
|
+
// Common fields
|
|
23
|
+
shape: options?.json?.shape || 'array-row-table',
|
|
24
|
+
batchType: 'partial-result',
|
|
25
|
+
data: [],
|
|
26
|
+
length: 0,
|
|
27
|
+
bytesUsed: 0,
|
|
28
|
+
// JSON additions
|
|
29
|
+
container: parser.getPartialResult(),
|
|
30
|
+
jsonpath
|
|
31
|
+
};
|
|
32
|
+
yield initialBatch;
|
|
33
|
+
}
|
|
34
|
+
isFirstChunk = false;
|
|
35
|
+
// schema = deduceSchema(rows);
|
|
36
|
+
}
|
|
37
|
+
// Add the row
|
|
38
|
+
for (const row of rows) {
|
|
39
|
+
tableBatchBuilder.addRow(row);
|
|
40
|
+
// If a batch has been completed, emit it
|
|
41
|
+
const batch = tableBatchBuilder.getFullBatch({ jsonpath });
|
|
42
|
+
if (batch) {
|
|
43
|
+
yield batch;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
tableBatchBuilder.chunkComplete(chunk);
|
|
47
|
+
const batch = tableBatchBuilder.getFullBatch({ jsonpath });
|
|
48
|
+
if (batch) {
|
|
49
|
+
yield batch;
|
|
50
|
+
}
|
|
37
51
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
});
|
|
43
|
-
if (batch) {
|
|
52
|
+
// yield final batch
|
|
53
|
+
const jsonpath = parser.getStreamingJsonPathAsString();
|
|
54
|
+
const batch = tableBatchBuilder.getFinalBatch({ jsonpath });
|
|
55
|
+
if (batch) {
|
|
44
56
|
yield batch;
|
|
45
|
-
}
|
|
46
57
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
58
|
+
if (metadata) {
|
|
59
|
+
const finalBatch = {
|
|
60
|
+
shape: 'json',
|
|
61
|
+
batchType: 'final-result',
|
|
62
|
+
container: parser.getPartialResult(),
|
|
63
|
+
jsonpath: parser.getStreamingJsonPathAsString(),
|
|
64
|
+
/** Data Just to avoid crashing? */
|
|
65
|
+
data: [],
|
|
66
|
+
length: 0
|
|
67
|
+
// schema: null
|
|
68
|
+
};
|
|
69
|
+
yield finalBatch;
|
|
53
70
|
}
|
|
54
|
-
}
|
|
55
|
-
const jsonpath = parser.getStreamingJsonPathAsString();
|
|
56
|
-
const batch = tableBatchBuilder.getFinalBatch({
|
|
57
|
-
jsonpath
|
|
58
|
-
});
|
|
59
|
-
if (batch) {
|
|
60
|
-
yield batch;
|
|
61
|
-
}
|
|
62
|
-
if (metadata) {
|
|
63
|
-
const finalBatch = {
|
|
64
|
-
shape: 'json',
|
|
65
|
-
batchType: 'final-result',
|
|
66
|
-
container: parser.getPartialResult(),
|
|
67
|
-
jsonpath: parser.getStreamingJsonPathAsString(),
|
|
68
|
-
data: [],
|
|
69
|
-
length: 0
|
|
70
|
-
};
|
|
71
|
-
yield finalBatch;
|
|
72
|
-
}
|
|
73
71
|
}
|
|
74
72
|
export function rebuildJsonObject(batch, data) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
return
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
73
|
+
// Last batch will have this special type and will provide all the root object of the parsed file
|
|
74
|
+
assert(batch.batchType === 'final-result');
|
|
75
|
+
// The streamed JSON data is a top level array (jsonpath = '$'), just return the array of row objects
|
|
76
|
+
if (batch.jsonpath === '$') {
|
|
77
|
+
return data;
|
|
78
|
+
}
|
|
79
|
+
// (jsonpath !== '$') The streamed data is not a top level array, so stitch it back in to the top-level object
|
|
80
|
+
if (batch.jsonpath && batch.jsonpath.length > 1) {
|
|
81
|
+
const topLevelObject = batch.container;
|
|
82
|
+
const streamingPath = new JSONPath(batch.jsonpath);
|
|
83
|
+
streamingPath.setFieldAtPath(topLevelObject, data);
|
|
84
|
+
return topLevelObject;
|
|
85
|
+
}
|
|
86
|
+
// No jsonpath, in this case nothing was streamed.
|
|
87
|
+
return batch.container;
|
|
86
88
|
}
|
|
87
|
-
//# sourceMappingURL=parse-json-in-batches.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { RowTable } from '@loaders.gl/schema';
|
|
2
|
-
import type { JSONLoaderOptions } from
|
|
2
|
+
import type { JSONLoaderOptions } from "../../json-loader.js";
|
|
3
3
|
export declare function parseJSONSync(jsonText: string, options: JSONLoaderOptions): RowTable;
|
|
4
4
|
//# sourceMappingURL=parse-json.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse-json.d.ts","sourceRoot":"","sources":["../../../src/lib/parsers/parse-json.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,oBAAoB,CAAC;AAEjD,OAAO,KAAK,EAAC,iBAAiB,EAAC,
|
|
1
|
+
{"version":3,"file":"parse-json.d.ts","sourceRoot":"","sources":["../../../src/lib/parsers/parse-json.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,oBAAoB,CAAC;AAEjD,OAAO,KAAK,EAAC,iBAAiB,EAAC,6BAA0B;AAEzD,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,QAAQ,CAWpF"}
|
|
@@ -1,29 +1,28 @@
|
|
|
1
1
|
import { makeTableFromData } from '@loaders.gl/schema';
|
|
2
2
|
export function parseJSONSync(jsonText, options) {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
try {
|
|
4
|
+
const json = JSON.parse(jsonText);
|
|
5
|
+
if (options.json?.table) {
|
|
6
|
+
const data = getFirstArray(json) || json;
|
|
7
|
+
return makeTableFromData(data);
|
|
8
|
+
}
|
|
9
|
+
return json;
|
|
10
|
+
}
|
|
11
|
+
catch (error) {
|
|
12
|
+
throw new Error('JSONLoader: failed to parse JSON');
|
|
9
13
|
}
|
|
10
|
-
return json;
|
|
11
|
-
} catch (error) {
|
|
12
|
-
throw new Error('JSONLoader: failed to parse JSON');
|
|
13
|
-
}
|
|
14
14
|
}
|
|
15
15
|
function getFirstArray(json) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
16
|
+
if (Array.isArray(json)) {
|
|
17
|
+
return json;
|
|
18
|
+
}
|
|
19
|
+
if (json && typeof json === 'object') {
|
|
20
|
+
for (const value of Object.values(json)) {
|
|
21
|
+
const array = getFirstArray(value);
|
|
22
|
+
if (array) {
|
|
23
|
+
return array;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
25
26
|
}
|
|
26
|
-
|
|
27
|
-
return null;
|
|
27
|
+
return null;
|
|
28
28
|
}
|
|
29
|
-
//# sourceMappingURL=parse-json.js.map
|
|
@@ -1,34 +1,32 @@
|
|
|
1
1
|
import { TableBatchBuilder } from '@loaders.gl/schema';
|
|
2
2
|
import { makeLineIterator, makeNumberedLineIterator, makeTextDecoderIterator } from '@loaders.gl/loader-utils';
|
|
3
3
|
export async function* parseNDJSONInBatches(binaryAsyncIterator, options) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
counter,
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
4
|
+
const textIterator = makeTextDecoderIterator(binaryAsyncIterator);
|
|
5
|
+
const lineIterator = makeLineIterator(textIterator);
|
|
6
|
+
const numberedLineIterator = makeNumberedLineIterator(lineIterator);
|
|
7
|
+
const schema = null;
|
|
8
|
+
const shape = 'row-table';
|
|
9
|
+
// @ts-ignore
|
|
10
|
+
const tableBatchBuilder = new TableBatchBuilder(schema, {
|
|
11
|
+
...options,
|
|
12
|
+
shape
|
|
13
|
+
});
|
|
14
|
+
for await (const { counter, line } of numberedLineIterator) {
|
|
15
|
+
try {
|
|
16
|
+
const row = JSON.parse(line);
|
|
17
|
+
tableBatchBuilder.addRow(row);
|
|
18
|
+
tableBatchBuilder.chunkComplete(line);
|
|
19
|
+
const batch = tableBatchBuilder.getFullBatch();
|
|
20
|
+
if (batch) {
|
|
21
|
+
yield batch;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
throw new Error(`NDJSONLoader: failed to parse JSON on line ${counter}`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const batch = tableBatchBuilder.getFinalBatch();
|
|
29
|
+
if (batch) {
|
|
23
30
|
yield batch;
|
|
24
|
-
}
|
|
25
|
-
} catch (error) {
|
|
26
|
-
throw new Error(`NDJSONLoader: failed to parse JSON on line ${counter}`);
|
|
27
31
|
}
|
|
28
|
-
}
|
|
29
|
-
const batch = tableBatchBuilder.getFinalBatch();
|
|
30
|
-
if (batch) {
|
|
31
|
-
yield batch;
|
|
32
|
-
}
|
|
33
32
|
}
|
|
34
|
-
//# sourceMappingURL=parse-ndjson-in-batches.js.map
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { makeTableFromData } from '@loaders.gl/schema';
|
|
2
2
|
export function parseNDJSONSync(ndjsonText) {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
3
|
+
const lines = ndjsonText.trim().split('\n');
|
|
4
|
+
const parsedLines = lines.map((line, counter) => {
|
|
5
|
+
try {
|
|
6
|
+
return JSON.parse(line);
|
|
7
|
+
}
|
|
8
|
+
catch (error) {
|
|
9
|
+
throw new Error(`NDJSONLoader: failed to parse JSON on line ${counter + 1}`);
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
return makeTableFromData(parsedLines);
|
|
12
13
|
}
|
|
13
|
-
//# sourceMappingURL=parse-ndjson.js.map
|