74 lines
1.8 KiB
JavaScript
74 lines
1.8 KiB
JavaScript
function createCSVScanner(onRow, nonJsonCols) {
|
|
let buffer = '';
|
|
|
|
return function scanChunk(chunk) {
|
|
buffer += chunk;
|
|
const lines = buffer.split('\n');
|
|
buffer = lines.pop(); // Save incomplete line
|
|
|
|
if(nonJsonCols !== 0)
|
|
{
|
|
for (const line of lines)
|
|
{
|
|
const fields = [];
|
|
let start = 0;
|
|
let commaCount = 0;
|
|
|
|
for (let i = 0; i < line.length; i++) {
|
|
if (line[i] === ',' && commaCount < nonJsonCols) {
|
|
fields.push(line.slice(start, i));
|
|
start = i + 1;
|
|
commaCount++;
|
|
}
|
|
}
|
|
|
|
const jsonStr = line.slice(start);
|
|
let jsonData = null;
|
|
try {
|
|
jsonData = JSON.parse(jsonStr);
|
|
} catch (_e) {
|
|
console.error('Invalid JSON:', jsonStr);
|
|
}
|
|
onRow(...fields, jsonData);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (const line of lines)
|
|
{
|
|
const fields = [];
|
|
let start = 0;
|
|
for (let i = 0; i < line.length; i++) {
|
|
if (line[i] === ',') {
|
|
fields.push(line.slice(start, i));
|
|
start = i + 1;
|
|
}
|
|
}
|
|
fields.push(line.slice(start, line.length-1))
|
|
onRow(...fields);
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
export default async function(url, nonJsonCols, onRow) {
|
|
const response = await fetch(url);
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
|
|
const reader = response.body.getReader();
|
|
const decoder = new TextDecoder("utf-8");
|
|
|
|
const scanner = createCSVScanner(onRow, nonJsonCols);
|
|
|
|
while (true)
|
|
{
|
|
const { done, value } = await reader.read();
|
|
if (done) break;
|
|
const chunk = decoder.decode(value, { stream: true });
|
|
scanner(chunk);
|
|
}
|
|
}
|