Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

bfj

Package Overview
Dependencies
Maintainers
1
Versions
48
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

bfj - npm Package Compare versions

Comparing version 1.1.0 to 1.2.0

4

HISTORY.md
# History
## 1.2.0
* Sanely handle circular references in the data when serialising.
## 1.1.0

@@ -4,0 +8,0 @@

2

package.json
{
"name": "bfj",
"version": "1.1.0",
"version": "1.2.0",
"description": "Big-friendly JSON. Asynchronous streaming functions for large JSON data sets.",

@@ -5,0 +5,0 @@ "homepage": "https://github.com/philbooth/bfj",

@@ -441,2 +441,13 @@ # BFJ

* `options.circular`:
By default,
circular references
will emit an error.
Set this property
to `'ignore'`
if you'd prefer
to silently skip past
circular references
in the data.
The emitted events

@@ -608,2 +619,15 @@ are defined

* `options.circular`:
By default,
circular references
will emit
a 'dataError' event
on the returned stream.
Set this property
to `'ignore'`
if you'd prefer
to silently skip past
circular references
in the data.
#### Example

@@ -616,2 +640,3 @@

stream.on('end', end);
stream.on('dataError', error);
```

@@ -695,2 +720,14 @@

* `options.circular`:
By default,
circular references
will reject
the returned promise.
Set this property
to `'ignore'`
if you'd prefer
to silently skip past
circular references
in the data.
#### Example

@@ -702,2 +739,5 @@

// :)
})
.catch(function (error) {
// :(
});

@@ -784,2 +824,14 @@ ```

* `options.circular`:
By default,
circular references
will cause the write
to fail.
Set this property
to `'ignore'`
if you'd prefer
to silently skip past
circular references
in the data.
#### Example

@@ -786,0 +838,0 @@

@@ -5,7 +5,6 @@ /*globals require, module, setImmediate, Promise, Buffer, Map */

var check, EventEmitter, error, events;
var check, EventEmitter, events;
check = require('check-types');
EventEmitter = require('events').EventEmitter;
error = require('./error');
events = require('./events');

@@ -30,9 +29,12 @@

*
* @option maps: 'object', or 'ignore', default is 'object'.
* @option maps: 'object' or 'ignore', default is 'object'.
*
* @option iterables: 'array', or 'ignore', default is 'array'.
* @option iterables: 'array' or 'ignore', default is 'array'.
*
* @option circular: 'error' or 'ignore', default is 'error'.
**/
function eventify (data, options) {
var coercions, emitter;
var references, coercions, emitter, ignoreCircularReferences, ignoreItems;
references = [];
coercions = {};

@@ -54,2 +56,6 @@ emitter = new EventEmitter();

normaliseOption('iterables');
if (options.circular === 'ignore') {
ignoreCircularReferences = true;
}
}

@@ -180,8 +186,19 @@

function array (datum) {
return collection(datum, 'array', proceed);
// For an array, collection:object and collection:array are the same.
return collection(datum, datum, 'array', proceed);
}
function collection (c, type, action) {
var resolve;
function collection (object, array, type, action) {
var ignoreThisItem, resolve;
if (references.indexOf(object) >= 0) {
ignoreThisItem = ignoreItems = true;
if (! ignoreCircularReferences) {
emitter.emit(events.error, new Error('Circular reference.'));
}
} else {
references.push(object);
}
emitter.emit(events[type]);

@@ -196,3 +213,11 @@

function item (index) {
if (index >= c.length) {
if (index >= array.length) {
if (ignoreThisItem) {
ignoreItems = false;
}
if (ignoreItems) {
return;
}
emitter.emit(events.endPrefix + events[type]);

@@ -203,3 +228,7 @@

action(c[index]).then(item.bind(null, index + 1));
if (ignoreItems) {
return item(index + 1);
}
action(array[index]).then(item.bind(null, index + 1));
}

@@ -209,3 +238,4 @@ }

function object (datum) {
return collection(Object.keys(datum), 'object', function (key) {
// For an object, collection:object and collection:array are different.
return collection(datum, Object.keys(datum), 'object', function (key) {
emitter.emit(events.property, key);

@@ -212,0 +242,0 @@

@@ -32,5 +32,7 @@ /*globals require, module */

*
* @option maps: 'object', or 'ignore', default is 'object'.
* @option maps: 'object' or 'ignore', default is 'object'.
*
* @option iterables: 'array', or 'ignore', default is 'array'.
* @option iterables: 'array' or 'ignore', default is 'array'.
*
* @option circular: 'error' or 'ignore', default is 'error'.
**/

@@ -61,2 +63,3 @@ function streamify (data, options) {

emitter.on(events.end, end);
emitter.on(events.error, error);

@@ -219,3 +222,7 @@ return stream;

}
function error (error) {
stream.emit('dataError', error);
}
}

@@ -27,8 +27,10 @@ /*globals require, module, Promise */

*
* @option maps: 'object', or 'ignore', default is 'object'.
* @option maps: 'object' or 'ignore', default is 'object'.
*
* @option iterables: 'array', or 'ignore', default is 'array'.
* @option iterables: 'array' or 'ignore', default is 'array'.
*
* @option circular: 'error' or 'ignore', default is 'error'.
**/
function stringify (data, options) {
var stream, json, resolve;
var stream, json, resolve, reject;

@@ -40,5 +42,7 @@ stream = streamify(data, options);

stream.on('end', end);
stream.on('dataError', error);
return new Promise(function (res) {
return new Promise(function (res, rej) {
resolve = res;
reject = rej;
});

@@ -53,3 +57,7 @@

}
function error (e) {
reject(e);
}
}

@@ -32,5 +32,7 @@ /*globals require, module, Promise */

*
* @option maps: 'object', or 'ignore', default is 'object'.
* @option maps: 'object' or 'ignore', default is 'object'.
*
* @option iterables: 'array', or 'ignore', default is 'array'.
* @option iterables: 'array' or 'ignore', default is 'array'.
*
* @option circular: 'error' or 'ignore', default is 'error'.
**/

@@ -43,7 +45,7 @@ function write (path, data, options) {

resolve();
}).on('error', function (error) {
reject(error);
});
})
.on('error', reject)
.on('dataError', reject);
});
}

@@ -1469,4 +1469,182 @@ 'use strict';

});
suite('array circular reference:', function () {
setup(function (done) {
var array, emitter;
array = [ 'foo' ];
array[1] = array;
emitter = eventify(array);
Object.keys(events).forEach(function (key) {
emitter.on(events[key], spooks.fn({
name: key,
log: log
}));
});
emitter.on(events.end, done);
});
test('array event occurred twice', function () {
assert.strictEqual(log.counts.array, 2);
});
test('string event occurred once', function () {
assert.strictEqual(log.counts.string, 1);
});
test('string event was dispatched correctly', function () {
assert.strictEqual(log.args.string[0][0], 'foo');
});
test('endArray event occurred twice', function () {
assert.strictEqual(log.counts.endArray, 2);
});
test('end event occurred once', function () {
assert.strictEqual(log.counts.end, 1);
});
test('error event occurred once', function () {
assert.strictEqual(log.counts.error, 1);
});
test('error event was dispatched correctly', function () {
assert.lengthOf(log.args.error[0], 1);
assert.instanceOf(log.args.error[0][0], Error);
assert.strictEqual(log.args.error[0][0].message, 'Circular reference.');
});
});
suite('object circular reference:', function () {
setup(function (done) {
var object, emitter;
object = { foo: 'bar' };
object.self = object;
emitter = eventify(object);
Object.keys(events).forEach(function (key) {
emitter.on(events[key], spooks.fn({
name: key,
log: log
}));
});
emitter.on(events.end, done);
});
test('object event occurred twice', function () {
assert.strictEqual(log.counts.object, 2);
});
test('property event occurred twice', function () {
assert.strictEqual(log.counts.property, 2);
});
test('property event was dispatched correctly first time', function () {
assert.strictEqual(log.args.property[0][0], 'foo');
});
test('property event was dispatched correctly second time', function () {
assert.strictEqual(log.args.property[1][0], 'self');
});
test('endObject event occurred twice', function () {
assert.strictEqual(log.counts.endObject, 2);
});
test('end event occurred once', function () {
assert.strictEqual(log.counts.end, 1);
});
test('error event occurred once', function () {
assert.strictEqual(log.counts.error, 1);
});
test('error event was dispatched correctly', function () {
assert.strictEqual(log.args.error[0][0].message, 'Circular reference.');
});
});
suite('array circular reference with ignore set:', function () {
setup(function (done) {
var array, emitter;
array = [ 'foo' ];
array[1] = array;
emitter = eventify(array, { circular: 'ignore' });
Object.keys(events).forEach(function (key) {
emitter.on(events[key], spooks.fn({
name: key,
log: log
}));
});
emitter.on(events.end, done);
});
test('array event occurred twice', function () {
assert.strictEqual(log.counts.array, 2);
});
test('string event occurred once', function () {
assert.strictEqual(log.counts.string, 1);
});
test('endArray event occurred twice', function () {
assert.strictEqual(log.counts.endArray, 2);
});
test('end event occurred once', function () {
assert.strictEqual(log.counts.end, 1);
});
test('error event did not occur', function () {
assert.strictEqual(log.counts.error, 0);
});
});
suite('object circular reference with ignore set:', function () {
setup(function (done) {
var object, emitter;
object = { foo: 'bar' };
object.self = object;
emitter = eventify(object, { circular: 'ignore' });
Object.keys(events).forEach(function (key) {
emitter.on(events[key], spooks.fn({
name: key,
log: log
}));
});
emitter.on(events.end, done);
});
test('object event occurred twice', function () {
assert.strictEqual(log.counts.object, 2);
});
test('property event occurred twice', function () {
assert.strictEqual(log.counts.property, 2);
});
test('endObject event occurred twice', function () {
assert.strictEqual(log.counts.endObject, 2);
});
test('end event occurred once', function () {
assert.strictEqual(log.counts.end, 1);
});
test('error event did not occur', function () {
assert.strictEqual(log.counts.error, 0);
});
});
});
});

@@ -36,3 +36,3 @@ 'use strict';

log: log,
archetype: { instance: { push: function () {} } },
archetype: { instance: { push: function () {}, emit: function () {} } },
results: results

@@ -133,4 +133,4 @@ }));

test('EventEmitter.on was called nine times', function () {
assert.strictEqual(log.counts.on, 9);
test('EventEmitter.on was called ten times', function () {
assert.strictEqual(log.counts.on, 10);
assert.strictEqual(log.these.on[0], results.eventify[0]);

@@ -145,2 +145,3 @@ assert.strictEqual(log.these.on[1], results.eventify[0]);

assert.strictEqual(log.these.on[8], results.eventify[0]);
assert.strictEqual(log.these.on[9], results.eventify[0]);
});

@@ -231,2 +232,16 @@

test('EventEmitter.on was called correctly tenth time', function () {
assert.lengthOf(log.args.on[9], 2);
assert.strictEqual(log.args.on[9][0], 'err');
assert.isFunction(log.args.on[9][1]);
assert.notStrictEqual(log.args.on[9][1], log.args.on[0][1]);
assert.notStrictEqual(log.args.on[9][1], log.args.on[1][1]);
assert.notStrictEqual(log.args.on[9][1], log.args.on[2][1]);
assert.notStrictEqual(log.args.on[9][1], log.args.on[3][1]);
assert.notStrictEqual(log.args.on[9][1], log.args.on[4][1]);
assert.notStrictEqual(log.args.on[9][1], log.args.on[6][1]);
assert.notStrictEqual(log.args.on[9][1], log.args.on[7][1]);
assert.notStrictEqual(log.args.on[9][1], log.args.on[8][1]);
});
suite('array event:', function () {

@@ -271,2 +286,6 @@ setup(function () {

});
test('stream.emit was not called', function () {
assert.strictEqual(log.counts.emit, 0);
});
});

@@ -300,2 +319,6 @@ });

});
test('stream.emit was not called', function () {
assert.strictEqual(log.counts.emit, 0);
});
});

@@ -421,2 +444,6 @@

});
test('stream.emit was not called', function () {
assert.strictEqual(log.counts.emit, 0);
});
});

@@ -560,2 +587,6 @@ });

});
test('stream.emit was not called', function () {
assert.strictEqual(log.counts.emit, 0);
});
});

@@ -611,2 +642,6 @@ });

});
test('stream.emit was not called', function () {
assert.strictEqual(log.counts.emit, 0);
});
});

@@ -648,2 +683,6 @@

});
test('stream.emit was not called', function () {
assert.strictEqual(log.counts.emit, 0);
});
})

@@ -669,2 +708,6 @@ });

});
test('stream.emit was not called', function () {
assert.strictEqual(log.counts.emit, 0);
});
});

@@ -689,2 +732,6 @@ });

});
test('stream.emit was not called', function () {
assert.strictEqual(log.counts.emit, 0);
});
});

@@ -715,4 +762,4 @@ });

test('EventEmitter.on was called nine times', function () {
assert.strictEqual(log.counts.on, 9);
test('EventEmitter.on was called ten times', function () {
assert.strictEqual(log.counts.on, 10);
});

@@ -893,2 +940,6 @@

});
test('stream.emit was not called', function () {
assert.strictEqual(log.counts.emit, 0);
});
});

@@ -925,3 +976,23 @@ });

});
test('stream.emit was not called', function () {
assert.strictEqual(log.counts.emit, 0);
});
});
suite('error event:', function () {
setup(function () {
log.args.on[9][1]('foo');
});
test('stream.emit was called once', function () {
assert.strictEqual(log.counts.emit, 1);
});
test('stream.emit was called correctly', function () {
assert.lengthOf(log.args.emit[0], 2);
assert.strictEqual(log.args.emit[0][0], 'dataError');
assert.strictEqual(log.args.emit[0][1], 'foo');
});
});
});

@@ -928,0 +999,0 @@ });

@@ -105,6 +105,7 @@ 'use strict';

test('stream.on was called twice', function () {
assert.strictEqual(log.counts.on, 2);
test('stream.on was called three times', function () {
assert.strictEqual(log.counts.on, 3);
assert.strictEqual(log.these.on[0], require('./streamify')());
assert.strictEqual(log.these.on[1], require('./streamify')());
assert.strictEqual(log.these.on[2], require('./streamify')());
});

@@ -124,2 +125,9 @@

test('stream.on was called correctly third time', function () {
assert.strictEqual(log.args.on[2][0], 'dataError');
assert.isFunction(log.args.on[2][1]);
assert.notStrictEqual(log.args.on[2][1], log.args.on[0][1]);
assert.notStrictEqual(log.args.on[2][1], log.args.on[1][1]);
});
test('promise is unfulfilled', function () {

@@ -175,2 +183,13 @@ assert.isUndefined(resolved);

});
suite('dataError event:', function () {
setup(function (d) {
done = d;
log.args.on[2][1]('wibble');
});
test('promise is rejected', function () {
assert.strictEqual(rejected, 'wibble');
});
});
});

@@ -177,0 +196,0 @@ });

@@ -148,5 +148,7 @@ 'use strict';

test('stream.on was called twice', function () {
assert.strictEqual(log.counts.on, 2);
test('stream.on was called three times', function () {
assert.strictEqual(log.counts.on, 3);
assert.strictEqual(log.these.on[0], require('./streamify')());
assert.strictEqual(log.these.on[1], require('./streamify')());
assert.strictEqual(log.these.on[2], require('./streamify')());
});

@@ -167,2 +169,10 @@

test('stream.on was called correctly third time', function () {
assert.lengthOf(log.args.on[2], 2);
assert.strictEqual(log.args.on[2][0], 'dataError');
assert.isFunction(log.args.on[2][1]);
assert.notStrictEqual(log.args.on[2][1], log.args.on[0][1]);
assert.strictEqual(log.args.on[2][1], log.args.on[1][1]);
});
test('promise was returned', function () {

@@ -229,2 +239,31 @@ assert.instanceOf(result, Promise);

});
suite('dispatch dataError event:', function () {
var resolved, error, passed, failed;
setup(function (done) {
passed = failed = false;
result.then(function (r) {
resolved = r;
passed = true;
done();
}).catch(function (e) {
error = e;
failed = true;
done();
});
log.args.on[2][1]('wibble');
});
teardown(function () {
resolved = error = passed = failed = undefined;
});
test('promise was rejected', function () {
assert.isTrue(failed);
assert.isFalse(passed);
assert.strictEqual(error, 'wibble');
});
});
});

@@ -231,0 +270,0 @@ });

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc