bfj 9.1.0 → 9.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.eslintrc CHANGED
@@ -145,7 +145,7 @@ rules:
145
145
  no-spaced-func: 2
146
146
  no-sparse-arrays: 2
147
147
  no-sync: 0
148
- no-ternary: 1
148
+ no-ternary: 0
149
149
  no-this-before-super: 2
150
150
  no-throw-literal: 1
151
151
  no-trailing-spaces: 2
package/HISTORY.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # History
2
2
 
3
+ ## 9.1.2
4
+
5
+ ### Bug fixes
6
+
7
+ * streamify: fix nonsense race condition mitigation (bcf35db58538b3e4feda31e4d0781ff16ee0d0a7)
8
+
9
+ ### Other changes
10
+
11
+ * deps: upgrade `cross-spawn` to `7.0.6` (4a55a0f3e8a0a6eadc3f43bd3c0f33eedb0619a6)
12
+ * eventify: remove redundant `async` (44d90b45f0f84423784ccd835dad20ca8209162b)
13
+ * lint: stop warning on ternary operators (4cb552cd2b69b0432ace5f326b2804f57010e69f)
14
+
15
+ ## 9.1.1
16
+
17
+ ### Bug fixes
18
+
19
+ * streamify: ensure array/object value are always followed by comma (a3ad4cbced8997f4030d8cf3a2466b2d3234611d)
20
+
3
21
  ## 9.1.0
4
22
 
5
23
  ### New features
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bfj",
3
- "version": "9.1.0",
3
+ "version": "9.1.2",
4
4
  "description": "Big-friendly JSON. Asynchronous streaming functions for large JSON data sets.",
5
5
  "homepage": "https://gitlab.com/philbooth/bfj",
6
6
  "bugs": "https://gitlab.com/philbooth/bfj/issues",
package/src/eventify.js CHANGED
@@ -209,7 +209,7 @@ function eventify (data, options = {}) {
209
209
  return datum > Number.NEGATIVE_INFINITY && datum < Number.POSITIVE_INFINITY
210
210
  }
211
211
 
212
- async function yieldThenProceed (datum, resolve, reject) {
212
+ function yieldThenProceed (datum, resolve, reject) {
213
213
  setImmediate(async () => {
214
214
  try {
215
215
  resolve(await afterCoercion(await coerce(datum)))
package/src/streamify.js CHANGED
@@ -50,6 +50,7 @@ function streamify (data, options = {}) {
50
50
  streamOptions = { highWaterMark }
51
51
  }
52
52
  const stream = new JsonStream(read, streamOptions)
53
+ const eventQueue = []
53
54
 
54
55
  let awaitPush = true
55
56
  let index = 0
@@ -58,7 +59,6 @@ function streamify (data, options = {}) {
58
59
  let isPaused = false
59
60
  let isProperty
60
61
  let length = 0
61
- let mutex = Promise.resolve()
62
62
  let needsComma
63
63
 
64
64
  emitter.on(events.array, noRacing(array))
@@ -122,8 +122,17 @@ function streamify (data, options = {}) {
122
122
 
123
123
  function noRacing (handler) {
124
124
  return async (eventData) => {
125
- await mutex
126
- mutex = await handler(eventData)
125
+ let resolve
126
+
127
+ eventQueue.push(new Promise(res => resolve = res))
128
+
129
+ if (eventQueue.length > 1) {
130
+ await eventQueue[eventQueue.length - 2]
131
+ eventQueue.shift()
132
+ }
133
+
134
+ await handler(eventData)
135
+ resolve()
127
136
  }
128
137
  }
129
138
 
@@ -219,6 +228,7 @@ function streamify (data, options = {}) {
219
228
  async function value (v) {
220
229
  await before()
221
230
  await addJson(`${v}`)
231
+ needsComma = true
222
232
  }
223
233
 
224
234
  async function endArray () {
@@ -423,6 +423,46 @@ suite('integration:', () => {
423
423
  })
424
424
  })
425
425
 
426
+ // https://gitlab.com/philbooth/bfj/-/issues/72
427
+ suite('issue #72:', () => {
428
+ let result
429
+
430
+ setup(async () => {
431
+ result = await bfj.stringify([
432
+ {
433
+ foo: 'bar',
434
+ wibble: 'blee',
435
+ },
436
+ {
437
+ foo: 'bar',
438
+ wibble: 'blee',
439
+ },
440
+ ])
441
+ })
442
+
443
+ test('result was correct', () => {
444
+ assert.strictEqual(result, '[{"foo":"bar","wibble":"blee"},{"foo":"bar","wibble":"blee"}]')
445
+ })
446
+ })
447
+
448
+ // https://gitlab.com/philbooth/bfj/-/issues/73
449
+ suite('issue #73:', () => {
450
+ const data = {
451
+ foo: 'bar',
452
+ wibble: 'blee',
453
+ }
454
+
455
+ let result
456
+
457
+ setup(async () => {
458
+ result = await bfj.stringify(data, { space: 2 })
459
+ })
460
+
461
+ test('stringify result was correct', () => {
462
+ assert.strictEqual(result, JSON.stringify(data, null, 2))
463
+ })
464
+ })
465
+
426
466
  suite('write object:', () => {
427
467
  let failed, file, result
428
468
 
@@ -431,7 +471,8 @@ suite('integration:', () => {
431
471
  file = path.join(__dirname, 'data.json')
432
472
  return bfj.write(
433
473
  file,
434
- { foo: [ 'b', 'a', 'r' ], baz: null, qux: 3.14159265359e42 }
474
+ { foo: [ 'b', 'a', 'r' ], bar: 'bar', blee: '', wibble: 'wibble', baz: null, qux: 3.14159265359e42 },
475
+ { bufferLength: 1 },
435
476
  )
436
477
  .then(() => {
437
478
  result = fs.readFileSync(file, { encoding: 'utf8' })
@@ -451,7 +492,7 @@ suite('integration:', () => {
451
492
  })
452
493
 
453
494
  test('result was correct', () => {
454
- assert.strictEqual(result, '{"foo":["b","a","r"],"baz":null,"qux":3.14159265359e+42}')
495
+ assert.strictEqual(result, '{"foo":["b","a","r"],"bar":"bar","blee":"","wibble":"wibble","baz":null,"qux":3.14159265359e+42}')
455
496
  })
456
497
  })
457
498
  })
@@ -694,6 +694,38 @@ suite('eventify:', () => {
694
694
  })
695
695
  })
696
696
 
697
+ suite('empty string:', () => {
698
+ setup(done => {
699
+ const emitter = eventify('')
700
+
701
+ Object.entries(events).forEach(([ key, value ]) => {
702
+ emitter.on(value, spooks.fn({
703
+ name: key,
704
+ log: log
705
+ }))
706
+ })
707
+
708
+ emitter.on(events.end, done)
709
+ })
710
+
711
+ test('string event occurred once', () => {
712
+ assert.strictEqual(log.counts.string, 1)
713
+ })
714
+
715
+ test('string event was dispatched correctly', () => {
716
+ assert.lengthOf(log.args.string[0], 1)
717
+ assert.strictEqual(log.args.string[0][0], '')
718
+ })
719
+
720
+ test('error event did not occur', () => {
721
+ assert.strictEqual(log.counts.error, 0)
722
+ })
723
+
724
+ test('dataError event did not occur', () => {
725
+ assert.strictEqual(log.counts.dataError, 0)
726
+ })
727
+ })
728
+
697
729
  suite('number:', () => {
698
730
  setup(done => {
699
731
  const emitter = eventify(42)
@@ -720,6 +720,38 @@ suite('streamify:', () => {
720
720
  })
721
721
  })
722
722
  })
723
+
724
+ suite('concurrent events:', () => {
725
+ setup(() => {
726
+ log.args.JsonStream[0][0]()
727
+ const promises = []
728
+ promises.push(log.args.on[1][1]())
729
+ promises.push(log.args.on[2][1]('foo'))
730
+ promises.push(log.args.on[3][1]('bar'))
731
+ promises.push(log.args.on[2][1]('wibble'))
732
+ promises.push(log.args.on[3][1]('blee'))
733
+ promises.push(log.args.on[7][1]())
734
+ return Promise.all(promises)
735
+ })
736
+
737
+ test('stream.push was called 7 times', () => {
738
+ assert.strictEqual(log.counts.push, 7)
739
+ })
740
+
741
+ test('stream.push was called correctly', () => {
742
+ assert.strictEqual(log.args.push[0][0], '{')
743
+ assert.strictEqual(log.args.push[1][0], '"foo":')
744
+ assert.strictEqual(log.args.push[2][0], '"bar"')
745
+ assert.strictEqual(log.args.push[3][0], ',')
746
+ assert.strictEqual(log.args.push[4][0], '"wibble":')
747
+ assert.strictEqual(log.args.push[5][0], '"blee"')
748
+ assert.strictEqual(log.args.push[6][0], '}')
749
+ })
750
+
751
+ test('stream.emit was not called', () => {
752
+ assert.strictEqual(log.counts.emit, 0)
753
+ })
754
+ })
723
755
  })
724
756
 
725
757
  suite('streamify with space option:', () => {
@@ -950,6 +982,43 @@ suite('streamify:', () => {
950
982
  })
951
983
  })
952
984
 
985
+ suite('concurrent events:', () => {
986
+ setup(() => {
987
+ log.args.JsonStream[0][0]()
988
+ const promises = []
989
+ promises.push(log.args.on[1][1]())
990
+ promises.push(log.args.on[2][1]('foo'))
991
+ promises.push(log.args.on[3][1]('bar'))
992
+ promises.push(log.args.on[2][1]('wibble'))
993
+ promises.push(log.args.on[3][1]('blee'))
994
+ promises.push(log.args.on[7][1]())
995
+ return Promise.all(promises)
996
+ })
997
+
998
+ test('stream.push was called 12 times', () => {
999
+ assert.strictEqual(log.counts.push, 12)
1000
+ })
1001
+
1002
+ test('stream.push was called correctly', () => {
1003
+ assert.strictEqual(log.args.push[0][0], '{')
1004
+ assert.strictEqual(log.args.push[1][0], '\n ')
1005
+ assert.strictEqual(log.args.push[2][0], '"foo":')
1006
+ assert.strictEqual(log.args.push[3][0], ' ')
1007
+ assert.strictEqual(log.args.push[4][0], '"bar"')
1008
+ assert.strictEqual(log.args.push[5][0], ',')
1009
+ assert.strictEqual(log.args.push[6][0], '\n ')
1010
+ assert.strictEqual(log.args.push[7][0], '"wibble":')
1011
+ assert.strictEqual(log.args.push[8][0], ' ')
1012
+ assert.strictEqual(log.args.push[9][0], '"blee"')
1013
+ assert.strictEqual(log.args.push[10][0], '\n')
1014
+ assert.strictEqual(log.args.push[11][0], '}')
1015
+ })
1016
+
1017
+ test('stream.emit was not called', () => {
1018
+ assert.strictEqual(log.counts.emit, 0)
1019
+ })
1020
+ })
1021
+
953
1022
  suite('read stream, end event:', () => {
954
1023
  setup(() => {
955
1024
  log.args.JsonStream[0][0]()