"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.withLatestFrom = void 0;
const Observable_js_1 = require("../Observable.js");
const identity_js_1 = require("../util/identity.js");
const noop_js_1 = require("../util/noop.js");
const args_js_1 = require("../util/args.js");
function withLatestFrom(...inputs) {
    const project = (0, args_js_1.popResultSelector)(inputs);
    return (source) => new Observable_js_1.Observable((destination) => {
        const len = inputs.length;
        const otherValues = new Array(len);
        let hasValue = inputs.map(() => false);
        let ready = false;
        for (let i = 0; i < len; i++) {
            (0, Observable_js_1.from)(inputs[i]).subscribe((0, Observable_js_1.operate)({
                destination,
                next: (value) => {
                    otherValues[i] = value;
                    if (!ready && !hasValue[i]) {
                        hasValue[i] = true;
                        (ready = hasValue.every(identity_js_1.identity)) && (hasValue = null);
                    }
                },
                complete: noop_js_1.noop,
            }));
        }
        source.subscribe((0, Observable_js_1.operate)({
            destination,
            next: (value) => {
                if (ready) {
                    const values = [value, ...otherValues];
                    destination.next(project ? project(...values) : values);
                }
            },
        }));
    });
}
exports.withLatestFrom = withLatestFrom;