You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
90 lines
1.9 KiB
90 lines
1.9 KiB
3 years ago
|
"use strict";
|
||
|
|
||
|
const {
|
||
|
createWriteStream
|
||
|
} = require('fs');
|
||
|
|
||
|
const {
|
||
|
Readable
|
||
|
} = require('stream');
|
||
|
|
||
|
class StatsSerializeStream extends Readable {
|
||
|
constructor(stats) {
|
||
|
super();
|
||
|
this._indentLevel = 0;
|
||
|
this._stringifier = this._stringify(stats);
|
||
|
}
|
||
|
|
||
|
get _indent() {
|
||
|
return ' '.repeat(this._indentLevel);
|
||
|
}
|
||
|
|
||
|
_read() {
|
||
|
let readMore = true;
|
||
|
|
||
|
while (readMore) {
|
||
|
const {
|
||
|
value,
|
||
|
done
|
||
|
} = this._stringifier.next();
|
||
|
|
||
|
if (done) {
|
||
|
this.push(null);
|
||
|
readMore = false;
|
||
|
} else {
|
||
|
readMore = this.push(value);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
*_stringify(obj) {
|
||
|
if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean' || obj === null) {
|
||
|
yield JSON.stringify(obj);
|
||
|
} else if (Array.isArray(obj)) {
|
||
|
yield '[';
|
||
|
this._indentLevel++;
|
||
|
let isFirst = true;
|
||
|
|
||
|
for (let item of obj) {
|
||
|
if (item === undefined) {
|
||
|
item = null;
|
||
|
}
|
||
|
|
||
|
yield `${isFirst ? '' : ','}\n${this._indent}`;
|
||
|
yield* this._stringify(item);
|
||
|
isFirst = false;
|
||
|
}
|
||
|
|
||
|
this._indentLevel--;
|
||
|
yield obj.length ? `\n${this._indent}]` : ']';
|
||
|
} else {
|
||
|
yield '{';
|
||
|
this._indentLevel++;
|
||
|
let isFirst = true;
|
||
|
const entries = Object.entries(obj);
|
||
|
|
||
|
for (const [itemKey, itemValue] of entries) {
|
||
|
if (itemValue === undefined) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
yield `${isFirst ? '' : ','}\n${this._indent}${JSON.stringify(itemKey)}: `;
|
||
|
yield* this._stringify(itemValue);
|
||
|
isFirst = false;
|
||
|
}
|
||
|
|
||
|
this._indentLevel--;
|
||
|
yield entries.length ? `\n${this._indent}}` : '}';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
exports.StatsSerializeStream = StatsSerializeStream;
|
||
|
exports.writeStats = writeStats;
|
||
|
|
||
|
async function writeStats(stats, filepath) {
|
||
|
return new Promise((resolve, reject) => {
|
||
|
new StatsSerializeStream(stats).on('end', resolve).on('error', reject).pipe(createWriteStream(filepath));
|
||
|
});
|
||
|
}
|