import { Observable } from '../core/Observable' import { Subscribable, SubscriptionObserver } from '../core/types.h' import { getSpecies } from '../helpers/getSpecies' import { createSubject } from './subject' export const groupBy = ( selector: (value: T) => K, stream: Subscribable ): Observable> => { const C = getSpecies(stream) return new C((observer) => { const groups = new Map, SubscriptionObserver]>() return stream.subscribe({ error(reason) { observer.error(reason) }, complete() { groups.forEach(([_, sink]) => sink.complete()) observer.complete() }, next(value) { const key = selector(value) let subject: [Observable, SubscriptionObserver] if (groups.has(key)) { subject = groups.get(key)! // WTF TS } else { subject = createSubject() observer.next(subject[0]) groups.set(key, subject) } subject[1].next(value) } }) }) }