Created
October 20, 2017 05:54
-
-
Save adrai/713b298fd83da0063910aa9f1674a5ed to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const util = require('util'); | |
const Transform = require('stream').Transform; | |
function Slicer (options) { | |
if (!(this instanceof Slicer)) { | |
return new Slicer(options); | |
} | |
Transform.call(this, options); | |
} | |
util.inherits(Slicer, Transform); | |
/** | |
* This function will be called from the supper class. | |
* | |
* Call `push(newChunk)` to pass along transformed output | |
* to the readable side. You may call 'push' zero or more times. | |
* Call `callback(err)` when you are done with this chunk. If you pass | |
* an error, then that'll put the hurt on the whole operation. If you | |
* never call callback(), then you'll never get another chunk. | |
* | |
* @param {Buffer} chunk Is an input chunk. | |
* @param {String} encoding The encoding for this chunk. | |
* @param {Function} callback The function, that will be called when this action is completed. | |
* `function(err){}` | |
* @private | |
*/ | |
Slicer.prototype._transform = function (chunk, encoding, done) { | |
this.push(chunk); | |
done(); | |
} | |
function getIdent(ident, level) { | |
var res = ''; | |
for (var idx = 0; idx < (ident * level); idx++) { | |
res += ' '; | |
} | |
return res; | |
} | |
function transformObject(obj, stream, options, level) { | |
const nl = options.ident > 0 ? '\n' : ''; | |
const space = options.ident > 0 ? ' ' : ''; | |
const identation = getIdent(options.ident, level); | |
const identation2 = getIdent(options.ident, level + 1); | |
stream.write(`{`); | |
const keys = Object.keys(obj); | |
keys.forEach((k, i) => { | |
stream.write(`${nl}${identation2}"${k}":${space}`); | |
transformValue(obj[k], stream, options, level + 1); | |
if (i + 1 < keys.length) { | |
stream.write(','); | |
} | |
}); | |
stream.write(`${nl}${identation}}`); | |
} | |
function transformValue(value, stream, options, level) { | |
const nl = options.ident > 0 ? '\n' : ''; | |
// const space = options.ident > 0 ? ' ' : ''; | |
const identation = getIdent(options.ident, level); | |
const identation2 = getIdent(options.ident, level + 1); | |
const type = Object.prototype.toString.call(value); | |
switch (type) { | |
case '[object Array]': | |
stream.write(`[`); | |
value.forEach((item, i) => { | |
stream.write(`${nl}${identation2}`); | |
transformValue(item, stream, options, level + 1); | |
if (i + 1 < value.length) { | |
stream.write(','); | |
} | |
}); | |
stream.write(`${nl}${identation}]`); | |
break; | |
case '[object Object]': | |
transformObject(value, stream, options, level); | |
break; | |
case '[object Number]': | |
case '[object Boolean]': | |
case '[object String]': | |
case '[object Date]': | |
case '[object Null]': | |
case '[object Undefined]': | |
default: | |
stream.write(`${JSON.stringify(value)}`); | |
} | |
} | |
module.exports = (obj, options) => { | |
if (typeof obj !== 'object') throw new Error('Please pass an object!'); | |
options = options || {}; | |
options.ident = options.ident || 0; | |
const stream = new Slicer(options); | |
process.nextTick(() => { | |
transformObject(obj, stream, options, 0); | |
stream.end(); | |
}); | |
return stream; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
usage:
jsonWriteStream(myLargeObject, { ident: 2 }).pipe(require('fs').createWriteStream('res.json'));