"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.groupBy = void 0;
const Observable_js_1 = require("../Observable.js");
const Subject_js_1 = require("../Subject.js");
function groupBy(keySelector, elementOrOptions, duration, connector) {
    return (source) => new Observable_js_1.Observable((destination) => {
        let element;
        if (!elementOrOptions || typeof elementOrOptions === 'function') {
            element = elementOrOptions;
        }
        else {
            ({ duration, element, connector } = elementOrOptions);
        }
        const groups = new Map();
        const notify = (cb) => {
            groups.forEach(cb);
            cb(destination);
        };
        const handleError = (err) => notify((consumer) => consumer.error(err));
        const groupBySourceSubscriber = (0, Observable_js_1.operate)({
            destination,
            next: (value) => {
                try {
                    const key = keySelector(value);
                    let group = groups.get(key);
                    if (!group) {
                        groups.set(key, (group = connector ? connector() : new Subject_js_1.Subject()));
                        const grouped = createGroupedObservable(key, group);
                        destination.next(grouped);
                        if (duration) {
                            const durationSubscriber = (0, Observable_js_1.operate)({
                                destination: group,
                                next: () => {
                                    group.complete();
                                    durationSubscriber?.unsubscribe();
                                },
                                finalize: () => groups.delete(key),
                            });
                            groupBySourceSubscriber.add((0, Observable_js_1.from)(duration(grouped)).subscribe(durationSubscriber));
                        }
                    }
                    group.next(element ? element(value) : value);
                }
                catch (err) {
                    handleError(err);
                }
            },
            error: handleError,
            complete: () => notify((consumer) => consumer.complete()),
            finalize: () => groups.clear(),
        });
        source.subscribe(groupBySourceSubscriber);
        function createGroupedObservable(key, groupSubject) {
            const result = new Observable_js_1.Observable((groupSubscriber) => groupSubject.subscribe(groupSubscriber));
            result.key = key;
            return result;
        }
    });
}
exports.groupBy = groupBy;//# sourceMappingURL=http://go/sourcemap/sourcemaps/31e8d61c448c7472e371505838a0fe34083dad50/node_modules/rxjs/dist/cjs/internal/operators/groupBy.js.map