stream-json
Advanced tools
Comparing version 0.6.0 to 0.6.1
{ | ||
"name": "stream-json", | ||
"version": "0.6.0", | ||
"version": "0.6.1", | ||
"description": "stream-json is a SAX-inspired stream components with a minimal memory footprint to parse huge JSON files. Includes utilities to stream Django-like JSON database dumps.", | ||
@@ -5,0 +5,0 @@ "homepage": "http://github.com/uhop/stream-json", |
@@ -25,2 +25,3 @@ # stream-json | ||
* `Assembler` to assemble full objects from an event stream. | ||
* `Stringer` to convert an event stream back to a JSON text stream. | ||
* `StreamArray` handles a frequent use case: a huge array of relatively small objects similar to [Django](https://www.djangoproject.com/)-produced database dumps. It streams array components individually taking care of assembling them automatically. | ||
@@ -403,2 +404,24 @@ * `StreamFilteredArray` is a companion for `StreamArray`. The difference is that it allows to filter out unneeded objects in an efficient way without assembling them fully. | ||
### utils/Stringer | ||
This stream component converts an event stream (described in this document) back to a JSON text stream. The common use is to filter/transform an input stream, then pipe it back to the original text form. | ||
Its `Writeable` part operates in an [objectMode](http://nodejs.org/api/stream.html#stream_object_mode), while its `Readable` part operates in a buffer mode. | ||
```js | ||
var makeSource = require("stream-json"); | ||
var Filter = require("stream-json/Filter"); | ||
var Stringer = require("stream-json/utils/Stringer"); | ||
var source = makeSource(sourceOptions), | ||
filter = new Filter(filterOptions), | ||
stringer = new Stringer(); | ||
// Example of use: | ||
source.output.pipe(filter).pipe(stringer).pipe(fs.createWriteStream(oname)); | ||
fs.createReadStream(fname).pipe(source.input); | ||
``` | ||
The test file for `Stringer`: `tests/test_stringer.js`. | ||
### utils/StreamArray | ||
@@ -696,8 +719,10 @@ | ||
- 0.5.3 *bug fix to allow empty JSON Streaming* | ||
- 0.5.2 *bug fixes in `Filter`* | ||
- 0.5.1 *corrected README* | ||
- 0.5.0 *added support for [JSON Streaming](https://en.wikipedia.org/wiki/JSON_Streaming)* | ||
- 0.6.1 *the technical release.* | ||
- 0.6.0 *added Stringer to convert event streams back to JSON.* | ||
- 0.5.3 *bug fix to allow empty JSON Streaming.* | ||
- 0.5.2 *bug fixes in `Filter`.* | ||
- 0.5.1 *corrected README.* | ||
- 0.5.0 *added support for [JSON Streaming](https://en.wikipedia.org/wiki/JSON_Streaming).* | ||
- 0.4.2 *refreshed dependencies.* | ||
- 0.4.1 *added `StreamObject` by [Sam Noedel](https://github.com/delta62)* | ||
- 0.4.1 *added `StreamObject` by [Sam Noedel](https://github.com/delta62).* | ||
- 0.4.0 *new high-performant Combo component, switched to the previous parser.* | ||
@@ -704,0 +729,0 @@ - 0.3.0 *new even faster parser, bug fixes.* |
@@ -15,5 +15,5 @@ "use strict"; | ||
var source = makeSource(), | ||
assembler = new Assembler(), | ||
pattern = { | ||
var source = makeSource(), | ||
stringer = new Stringer(), | ||
pattern = { | ||
a: [[[]]], | ||
@@ -34,12 +34,48 @@ b: {a: 1}, | ||
stream.output.on("data", function(data) { | ||
source.output.pipe(stringer); | ||
stringer.on("data", function(data) { | ||
buffer += data; | ||
}); | ||
stream.output.on("end", function(){ | ||
eval(t.TEST("string === buffer")); | ||
stringer.on("end", function() { | ||
eval(t.TEST('string === buffer')); | ||
async.done(); | ||
}); | ||
new ReadString(string).pipe(stream.input); | ||
new ReadString(string).pipe(source.input); | ||
}, | ||
function test_stringer_json_stream (t) { | ||
var async = t.startAsync("test_stringer_json_stream"); | ||
var source = makeSource({jsonStreaming: true}), | ||
stringer = new Stringer(), | ||
pattern = { | ||
a: [[[]]], | ||
b: {a: 1}, | ||
c: {a: 1, b: 2}, | ||
d: [true, 1, "'x\"y'", null, false, true, {}, [], ""], | ||
e: 1, | ||
f: "", | ||
g: true, | ||
h: false, | ||
i: null, | ||
j: [], | ||
k: {} | ||
}, | ||
string = JSON.stringify(pattern), | ||
buffer = ''; | ||
string += string; | ||
source.output.pipe(stringer); | ||
stringer.on("data", function(data) { | ||
buffer += data; | ||
}); | ||
stringer.on("end", function() { | ||
eval(t.TEST('string === buffer')); | ||
async.done(); | ||
}); | ||
new ReadString(string).pipe(source.input); | ||
} | ||
]); |
@@ -13,6 +13,10 @@ 'use strict'; | ||
this._prev = ''; | ||
this._depth = 0; | ||
} | ||
util.inherits(Stringer, Transform); | ||
var noCommaAfter = {startObject: 1, startArray: 1, endKey: 1}, | ||
var noCommaAfter = {startObject: 1, startArray: 1, endKey: 1}, | ||
depthIncrement = {startObject: 1, startArray: 1}, | ||
depthDecrement = {endObject: 1, endArray: 1}, | ||
values = {keyValue: 1, stringValue: 1, numberValue: 1}, | ||
symbols = { | ||
@@ -27,30 +31,28 @@ startObject: '{', endObject: '}', | ||
Stringer.prototype._transform = function transform (chunk, encoding, callback) { | ||
switch (chunk.name) { | ||
case 'endObject': | ||
case 'endArray': | ||
case 'endKey': | ||
case 'endString': | ||
case 'endNumber': | ||
this.push(symbols[chunk.name]); | ||
break; | ||
case 'stringChunk': | ||
this.push(chunk.value.replace(/\"/g, '\\"')); | ||
break; | ||
case 'numberChunk': | ||
this.push(chunk.value); | ||
break; | ||
default: | ||
// case 'startObject': | ||
// case 'startArray': | ||
// case 'startKey': | ||
// case 'startString': | ||
// case 'startNumber': | ||
// case 'nullValue': | ||
// case 'truelValue': | ||
// case 'falseValue': | ||
if (noCommaAfter[this._prev] !== 1) this.push(','); | ||
this.push(symbols[chunk.name]); | ||
break; | ||
if (values[chunk.name] !== 1) { // filter out values | ||
switch (chunk.name) { | ||
case 'endObject': case 'endArray': case 'endKey': case 'endString': | ||
case 'endNumber': | ||
this.push(symbols[chunk.name]); | ||
break; | ||
case 'stringChunk': | ||
this.push(chunk.value.replace(/\"/g, '\\"')); | ||
break; | ||
case 'numberChunk': | ||
this.push(chunk.value); | ||
break; | ||
default: | ||
// case 'startObject': case 'startArray': case 'startKey': case 'startString': | ||
// case 'startNumber': case 'nullValue': case 'truelValue': case 'falseValue': | ||
if (this._depth && noCommaAfter[this._prev] !== 1) this.push(','); | ||
this.push(symbols[chunk.name]); | ||
break; | ||
} | ||
if (depthIncrement[chunk.name]) { | ||
++this._depth; | ||
} else if (depthDecrement[chunk.name]) { | ||
--this._depth; | ||
} | ||
this._prev = chunk.name; | ||
} | ||
this._prev = chunk.name; | ||
callback(); | ||
@@ -57,0 +59,0 @@ }; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
222910
3981
745
250