statsUtils.js 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. "use strict";
  2. const {
  3. createWriteStream
  4. } = require('fs');
  5. const {
  6. Readable
  7. } = require('stream');
  8. class StatsSerializeStream extends Readable {
  9. constructor(stats) {
  10. super();
  11. this._indentLevel = 0;
  12. this._stringifier = this._stringify(stats);
  13. }
  14. get _indent() {
  15. return ' '.repeat(this._indentLevel);
  16. }
  17. _read() {
  18. let readMore = true;
  19. while (readMore) {
  20. const {
  21. value,
  22. done
  23. } = this._stringifier.next();
  24. if (done) {
  25. this.push(null);
  26. readMore = false;
  27. } else {
  28. readMore = this.push(value);
  29. }
  30. }
  31. }
  32. *_stringify(obj) {
  33. if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean' || obj === null) {
  34. yield JSON.stringify(obj);
  35. } else if (Array.isArray(obj)) {
  36. yield '[';
  37. this._indentLevel++;
  38. let isFirst = true;
  39. for (let item of obj) {
  40. if (item === undefined) {
  41. item = null;
  42. }
  43. yield `${isFirst ? '' : ','}\n${this._indent}`;
  44. yield* this._stringify(item);
  45. isFirst = false;
  46. }
  47. this._indentLevel--;
  48. yield obj.length ? `\n${this._indent}]` : ']';
  49. } else {
  50. yield '{';
  51. this._indentLevel++;
  52. let isFirst = true;
  53. const entries = Object.entries(obj);
  54. for (const [itemKey, itemValue] of entries) {
  55. if (itemValue === undefined) {
  56. continue;
  57. }
  58. yield `${isFirst ? '' : ','}\n${this._indent}${JSON.stringify(itemKey)}: `;
  59. yield* this._stringify(itemValue);
  60. isFirst = false;
  61. }
  62. this._indentLevel--;
  63. yield entries.length ? `\n${this._indent}}` : '}';
  64. }
  65. }
  66. }
  67. exports.StatsSerializeStream = StatsSerializeStream;
  68. exports.writeStats = writeStats;
  69. async function writeStats(stats, filepath) {
  70. return new Promise((resolve, reject) => {
  71. new StatsSerializeStream(stats).on('end', resolve).on('error', reject).pipe(createWriteStream(filepath));
  72. });
  73. }