90 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			90 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| "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));
 | |
|   });
 | |
| } |