@bemedev/rx-add-ons
Version:
A collection of RxJS operators and utilities to enhance reactive programming capabilities.
72 lines (68 loc) • 2.72 kB
JavaScript
;
var rxjs = require('rxjs');
var timer = require('rxjs/internal/observable/timer');
var buffer = require('rxjs/internal/operators/buffer');
var filter = require('rxjs/internal/operators/filter');
var share = require('rxjs/internal/operators/share');
/**
* Groups emissions by time windows. Emits arrays of values collected within each time window.
*
* @param min - Time window size in milliseconds
* @param max - Optional maximum buffer size (defaults to no limit)
* @returns A function that returns an Observable that emits arrays of grouped values
*
* @example
* ```typescript
* // Group emissions every 1000ms
* source$.pipe(groupByTime(1000))
*
* // Group emissions every 500ms with max 10 items per group
* source$.pipe(groupByTime(500, 10))
* ```
*/
function groupByTime(min, max) {
return (source) => {
const shared = source.pipe(share.share());
if (max) {
return new rxjs.Observable(subscriber => {
let buffer = [];
let windowStart = Date.now();
const sourceSubscription = shared.subscribe({
next: value => {
buffer.push(value);
// Check if buffer is full or window time has passed
const now = Date.now();
if (buffer.length >= max || now - windowStart >= min) {
if (buffer.length > 0) {
subscriber.next([...buffer]);
buffer = [];
windowStart = now;
}
}
},
error: err => {
if (buffer.length > 0) {
subscriber.next([...buffer]);
buffer = [];
windowStart = Date.now();
}
subscriber.error(err);
},
complete: () => {
// Emit remaining buffer on completion
if (buffer.length > 0) {
subscriber.next([...buffer]);
}
subscriber.complete();
},
});
return sourceSubscription.unsubscribe;
});
}
const trigger = timer.timer(min, min);
// Simple time-based grouping without buffer size limit
return shared.pipe(buffer.buffer(trigger), filter.filter(group => group.length > 0));
};
}
exports.groupByTime = groupByTime;
//# sourceMappingURL=groupByTime.cjs.map