Skip to content

Commit

Permalink
fix: store emitted events and re-emit them for late listeners
Browse files Browse the repository at this point in the history
  • Loading branch information
nlf committed May 19, 2022
1 parent 0deb78e commit 24814ec
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 1 deletion.
23 changes: 22 additions & 1 deletion lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ const getOptString = options => !options || !options.length

const _onEnd = Symbol('_onEnd')
const _getOptions = Symbol('_getOptions')
const _emittedSize = Symbol('_emittedSize')
const _emittedIntegrity = Symbol('_emittedIntegrity')
const _emittedVerified = Symbol('_emittedVerified')

class IntegrityStream extends MiniPass {
constructor (opts) {
super()
Expand Down Expand Up @@ -63,6 +67,18 @@ class IntegrityStream extends MiniPass {
this.optString = getOptString(options)
}

on (ev, handler) {
if (ev === 'size' && this[_emittedSize]) {
return handler(this[_emittedSize])
}

if (ev === 'integrity' && this[_emittedIntegrity]) {
return handler(this[_emittedIntegrity])
}

return super.on(ev, handler)
}

emit (ev, data) {
if (ev === 'end') {
this[_onEnd]()
Expand Down Expand Up @@ -103,9 +119,14 @@ class IntegrityStream extends MiniPass {
err.sri = this.sri
this.emit('error', err)
} else {
this[_emittedSize] = this.size
this.emit('size', this.size)
this[_emittedIntegrity] = newSri
this.emit('integrity', newSri)
match && this.emit('verified', match)
if (match) {
this[_emittedVerified] = match
this.emit('verified', match)
}
}
}
}
Expand Down
34 changes: 34 additions & 0 deletions test/integrity-stream.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,42 @@ test('generates integrity', t => {
stream.on('integrity', i => {
integrity = i
})
let size
stream.on('size', s => {
size = s
})
stream.on('end', () => {
t.equal(collected, 'foo', 'stream output is complete')
t.equal(size, 3, 'size emitted')
t.same(integrity, TARGET, 'matching integrity emitted')
t.end()
})
stream.end()
})

test('re-emits for late listeners', t => {
const TARGET = ssri.fromData('foo')
const stream = ssri.integrityStream()
stream.write('foo')
let collected = ''
stream.on('data', d => {
collected += d.toString()
})

stream.on('end', () => {
// we add the listeners _after_ the end event this time to ensure that the events
// get emitted again for late listeners
let integrity
stream.on('integrity', i => {
integrity = i
})

let size
stream.on('size', s => {
size = s
})
t.equal(collected, 'foo', 'stream output is complete')
t.equal(size, 3, 'size emitted')
t.same(integrity, TARGET, 'matching integrity emitted')
t.end()
})
Expand Down

0 comments on commit 24814ec

Please sign in to comment.