forked from ColinEberhardt/d3fc-webgl-hathi-explorer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
streaming-tsv-parser.js
83 lines (65 loc) · 1.97 KB
/
streaming-tsv-parser.js
1
2
3
4
5
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// a TSV parser that parses the data incrementally in chunks
const tsvChunkedParser = () => {
const textDecoder = new TextDecoder("utf-8");
let columnHeadings;
let previousChunk = "";
return {
parseChunk(chunk) {
// decode and split into lines
const textData = textDecoder.decode(chunk) + previousChunk;
const lines = textData.split("\n");
// the first line is our column headings
if (!columnHeadings) {
columnHeadings = lines[0].split("\t");
lines.shift();
}
// the last line is probably partial - so append to the next chunk
previousChunk = lines.pop();
// convert each row to an object
const items = lines
.map(row => {
const cells = row.split("\t");
if (cells.length !== columnHeadings.length) {
return null;
}
let rowValue = {};
columnHeadings.forEach((h, i) => {
rowValue[h] = cells[i];
});
return rowValue;
})
.filter(i => i);
return items;
}
};
};
onmessage = async ({ data: filename }) => {
let totalBytes = 0;
const tsvParser = tsvChunkedParser();
const response = await fetch(filename);
if (!response.body) {
throw Error("ReadableStream not yet supported in this browser.");
}
const streamedResponse = new Response(
new ReadableStream({
start(controller) {
const reader = response.body.getReader();
const read = async () => {
const { done, value } = await reader.read();
if (done) {
controller.close();
return;
}
const items = tsvParser.parseChunk(value);
totalBytes += value.byteLength;
postMessage({ items, totalBytes });
controller.enqueue(value);
read();
};
read();
}
})
);
const data = await streamedResponse.text();
postMessage({ items: [], totalBytes: data.length, finished: true });
};