Bacon.holdWhen
available since about 0.7.14 does almost what you want, although buffered events are emitted one by one:
stream.holdWhen(valve) pauses and buffers the event stream if last event in valve is truthy. All buffered events are released when valve becomes falsy.
If you need to emit buffered events as a single event, you can try something like the following:
// source streams
var sourceObservable = Bacon.interval(1000);
var closingSelector = new Bacon.Bus();
// Constructing a new Observable where we're going to keep our state.
//
// We need to keep track of two things:
// - the buffer that is currently being filled, and
// - a previous buffer that is being flushed.
// The state will then look like this:
// [ buffer, flushed]
// where both buffer and flushed is an array of events from the source observable.
// empty initial state
var initialState = {buffer: [], flushed: []}
// There are two operations on the state: appending a new element to the buffer
// and flushing the current buffer:
// append each event from the source observable to the buffer,
// keeping flushed unchanged
var appends = sourceObservable.map(function(e) {
return function(state) {
state.buffer.push(e); return state;
}
});
// each event from the closingSelector replaces the `flushed` with
// the `buffer`'s contents, inserting an empty buffer.
var flushes = closingSelector.map(function(_) {
return function(state) { return {buffer: [], flushed: state.buffer} }
})
// merge appends and flushes into a single stream and apply them to the initial state
var ops = appends.merge(flushes)
var state = ops.scan(initialState, function(acc, f) { return f(acc) });
// resulting stream of flushed events
var flushed = state.sampledBy(closingSelector).map(function(state) { return state.flushed })
// triggered with `closingSelector.push({})`
flushed.onValue(function(x) { console.log("flushed", x) })