Source: operators/sort/sort.js

const reusable = require("../../helpers/reusable/reusable");

/**
 * Cannot be used with infinite collections, it will cause an infinite loop.
 * Is not entirely lazily evaluated, all values are pulled from source
 * immediately but are sorted only as requested.
 * @function sort
 * @template T
 * @param {Comparator<T>} comparator
 * @returns {Operator<T, T>} an Operator that emits values from source in
 * the order of largest to smallest using comparator.
 */
module.exports = comparator => reusable(
    function*(source) {
        let remainingValues = Array.from(source);
        while (remainingValues.length > 0) {
            for (let index = remainingValues.length; index > 0; index--) {
                let currentValue = remainingValues[index];
                let nextIndex = index - 1;
                let nextValue = remainingValues[nextIndex];
                if (comparator(currentValue, nextValue) < 0) {
                    remainingValues[index] = nextValue;
                    remainingValues[nextIndex] = currentValue;
                }
            }
            yield remainingValues.shift();
        }
    }
);