interval-management
Version:
No dependency interval management library, able to work with numbers, string, Dates or special objects
411 lines (410 loc) • 17.3 kB
JavaScript
"use strict";
var __spreadArrays = (this && this.__spreadArrays) || function () {
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
for (var r = Array(s), k = 0, i = 0; i < il; i++)
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
r[k] = a[j];
return r;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createInterval = void 0;
var index_1 = __importDefault(require("../index"));
exports.createInterval = function (equals, isLessThan, infinity) {
var min = function (a, b) { return hasInfinity(a, b) ? getInfinity(a, b) : (isLessThan(a, b) ? a : b); };
var max = function (a, b) { return hasInfinity(a, b) ? getNotInfinity(a, b) : isLessThan(a, b) ? b : a; };
var less = function (a, b) { return hasInfinity(a, b) ? infinityIsMore(a, b, false) : isLessThan(a, b); };
var lessOrEqual = function (a, b) { return hasInfinity(a, b) ? infinityIsMore(a, b, true) : (isLessThan(a, b) || equals(a, b)); };
var moreOrEqual = function (a, b) { return hasInfinity(a, b) ? infinityIsMore(b, a, true) : (isLessThan(b, a) || equals(a, b)); };
var safeEquals = function (a, b) { return a === infinity && b === infinity || (!hasInfinity(a, b) && equals(a, b)); };
var getInfinity = function (a, b) { return a === infinity ? a : b; };
var getNotInfinity = function (a, b) { return a === infinity ? b : a; };
var infinityIsMore = function (a, b, equal) {
if (a === b && equal) {
return true;
}
if (a === infinity && b !== infinity) {
return false; // a is more than b
}
return true;
};
var hasInfinity = function (a, b) { return (a === infinity || b === infinity); };
var concatNext = function (a, b) { return function (current) {
if (b.has(current)) {
return b.usedNext(current);
}
else if (a.has(current)) {
return a.usedNext(current);
}
else if (less(a.end, current) && less(current, b.start)) {
return b.start;
}
return b.end;
}; };
var checkInterval = function (start, end) {
if (end !== infinity && isLessThan(end, start)) {
throw new Error('End of interval cannot come before start');
}
if (start === infinity) {
throw new Error('Cannot start the interval at infinity');
}
};
var generalInterval = function (start, end, next) {
checkInterval(start, end);
var interval = function (start, end, next) {
checkInterval(start, end || infinity);
interval.start = start;
interval.current = start;
if (end) {
interval.end = end;
}
if (next) {
interval.usedNext = next;
}
interval.isDone = false;
return interval;
};
interval.isDone = false;
interval.done = function () { return interval.isDone; };
interval.usedNext = next;
interval.start = start;
interval.current = start;
interval.end = end;
interval.it = function (iterator) {
if (iterator <= 0) {
return interval;
}
if (less(interval.current, interval.end)) {
var nextValue = interval.usedNext(interval.current);
if (less(nextValue, interval.end)) {
interval.current = nextValue;
return interval.it(iterator - 1);
}
if (safeEquals(nextValue, interval.end)) {
interval.current = nextValue;
return interval;
}
if (less(interval.end, nextValue)) {
interval.isDone = true;
return interval;
}
}
if (safeEquals(interval.current, interval.end)) {
interval.isDone = true;
return interval;
}
throw Error('Iterator sanity check failed!');
};
interval.next = function () { return interval.it(1); };
interval.val = function () { return interval.current; };
interval.concat = function (nextInterval) { return generalInterval(min(interval.start, nextInterval.start), max(interval.end, nextInterval.end), less(interval.end, nextInterval.end)
? concatNext(interval, nextInterval)
: concatNext(nextInterval, interval)); };
interval.has = function (value) { return moreOrEqual(value, interval.start) && lessOrEqual(value, interval.end); };
interval.diff = function (nextInterval) {
if (!interval.overlap(nextInterval)) {
return interval;
}
if (lessOrEqual(interval.start, nextInterval.start) && lessOrEqual(interval.end, nextInterval.end)) {
return generalInterval(interval.start, nextInterval.start, interval.usedNext);
}
if (moreOrEqual(interval.start, nextInterval.start) && moreOrEqual(interval.end, nextInterval.end)) {
return generalInterval(nextInterval.end, interval.end, interval.usedNext);
}
if (interval.isInside(nextInterval)) {
return null;
}
return generalInterval(interval.start, interval.end, function (next) {
if (less(next, nextInterval.start)) {
return interval.usedNext(next);
}
if (lessOrEqual(nextInterval.end, next)) {
return interval.usedNext(next);
}
return nextInterval.end;
});
};
interval.overlap = function (nextInterval) { return interval.has(nextInterval.start) || interval.has(nextInterval.end); };
interval.isInside = function (nextInterval) { return nextInterval.has(interval.start) && nextInterval.has(interval.end); };
interval.compare = function (nextInterval) { return interval.overlap(nextInterval) ? 0 : (less(interval.start, nextInterval.start) ? -1 : 1); };
interval.copy = function () {
var copied = generalInterval(interval.start, interval.end, interval.usedNext);
copied.current = interval.current;
return copied;
};
interval.fillIn = function (intervals) {
if (!intervals || intervals.length === 0) {
return interval;
}
var sorted = interval.sort(intervals);
var filler = sorted[0];
for (var i = 0; i < sorted.length; i++) {
var at = sorted[i];
if (moreOrEqual(filler.end, at.start)) {
filler = filler.concat(at);
}
else {
filler = filler.concat(interval(filler.end, at.start, interval.usedNext).concat(at));
}
}
return filler;
};
interval.sort = function (intervals) { return __spreadArrays(intervals).sort(function (a, b) { return a.compare(b); }); };
interval.array = function () {
if (interval.end === infinity) {
throw Error('Cannot count to Infinity!');
}
if (interval.done()) {
return [];
}
var aggregate = [];
var copyInterval = interval.copy();
while (!copyInterval.done()) {
aggregate.push(copyInterval.val());
copyInterval.next();
}
return aggregate;
};
interval.split = function (split) {
var intervals = [];
if (interval.end === infinity) {
throw Error('Cannot split infinite interval');
}
var items = interval.array();
var start = items[0];
var end = items[items.length - 1];
items.forEach(function (item, i) {
var next = items[i + 1];
if (i === items.length - 1) {
intervals.push(generalInterval(start, end, interval.usedNext));
}
else if (!split(item, next, i)) {
intervals.push(generalInterval(start, item, interval.usedNext));
start = next;
}
});
return intervals;
};
var findHelper = function (compare, end) {
if (!end && end !== 0 && interval.end === infinity) {
throw Error('Cannot seek inside infinite interval without boundary');
}
var trueEnd = (interval.end === infinity || end || end === 0) ? end : interval.end;
var trueCompare = typeof compare === 'function' ? compare : function (item) { return safeEquals(item, compare); };
var copyInterval = generalInterval(interval.start, trueEnd, interval.usedNext);
return {
trueCompare: trueCompare,
copyInterval: copyInterval,
};
};
interval.find = function (compare, end) {
if (typeof compare !== 'function' && !interval.has(compare)) {
return null;
}
var _a = findHelper(compare, end), trueCompare = _a.trueCompare, copyInterval = _a.copyInterval;
while (!copyInterval.done()) {
if (trueCompare(copyInterval.val())) {
return copyInterval.val();
}
copyInterval.next();
}
return null;
};
interval.all = function (compare, end) {
if (typeof compare !== 'function' && !interval.has(compare)) {
return [];
}
var _a = findHelper(compare, end), trueCompare = _a.trueCompare, copyInterval = _a.copyInterval;
var aggregate = [];
while (!copyInterval.done()) {
if (trueCompare(copyInterval.val())) {
aggregate.push(copyInterval.val());
}
copyInterval.next();
}
return aggregate;
};
interval.convert = function (to, next, compare) {
var nextEnd;
var nextStart = to(interval.start);
if (interval.end === infinity) {
switch (typeof nextStart) {
case 'number':
case 'boolean':
nextEnd = Infinity;
break;
case 'string':
case 'object':
nextEnd = null;
break;
}
}
else {
nextEnd = to(interval.end);
}
if (!next) {
if (safeEquals(nextEnd, infinity)) {
throw Error('Cannot convert an infinite interval without next function');
}
return index_1.default(interval.array().map(to));
}
var converted = index_1.default(nextStart, nextEnd, next, compare);
converted.current = to(interval.current);
return converted;
};
var mapper = function (inter, fn) {
var stop = false;
var copied = inter.copy();
var escape = function () { return stop = true; };
fn(copied, function () { return stop; }, escape);
};
interval.map = function (iterator) {
var aggregate = [];
mapper(interval, function (copied, stop, escape) {
while (!stop()) {
aggregate.push(iterator(copied.val(), escape));
copied.next();
if (copied.done()) {
break;
}
}
});
return aggregate;
};
interval.forEach = function (iterator) { return mapper(interval, function (copied, stop, escape) {
while (!copied.done() && !stop()) {
iterator(copied.val(), escape);
copied.next();
}
}); };
interval.reduce = function (iterator, start) {
var aggregate = start;
mapper(interval, function (copied, stop, escape) {
while (!copied.done() && !stop()) {
aggregate = iterator(aggregate, copied.val(), escape);
copied.next();
}
});
return aggregate;
};
interval.closest = function (item) {
if (less(item, interval.start)) {
return [interval.start];
}
if (less(interval.end, item)) {
return [interval.end];
}
var last = interval.start;
var toReturn = [];
mapper(interval, function (copied, stop, escape) {
while (!copied.done() && !stop()) {
if (safeEquals(copied.val(), item)) {
escape();
toReturn = [copied.val()];
}
if (less(last, item) && less(item, copied.val())) {
escape();
toReturn = [last, copied.val()];
}
last = copied.val();
copied.next();
}
});
if (toReturn.length === 0) {
throw Error('Unexpected result of closest function');
}
return toReturn;
};
interval.reset = function () {
interval.current = interval.start;
interval.isDone = false;
return interval;
};
interval.deep = function () { return index_1.default(interval.array()); };
interval.classify = function (classify) {
var split = interval.split(function (current, next) { return classify(current) === classify(next); });
var map = {};
split.forEach(function (int) {
var index = classify(int.start);
if (!map[index]) {
map[index] = [];
}
map[index].push(int);
});
return map;
};
interval.merge = function (int) { return index_1.default(__spreadArrays(interval.array(), int.array()).sort(function (a, b) { return safeEquals(a, b) ? 0 : (less(a, b) ? -1 : 1); })); };
interval.pop = function () {
if (interval.isDone) {
return null;
}
var prevStart = interval.start;
interval.start = interval.usedNext(prevStart);
interval.current = interval.usedNext(prevStart);
return prevStart;
};
interval.push = function (item) {
if (safeEquals(item, infinity)) {
throw Error('Cannot push into infinite interval');
}
var prevEnd = interval.end;
var prevUsed = interval.usedNext;
interval.isDone = false;
interval.usedNext = function (current) {
if (safeEquals(current, prevEnd)) {
return item;
}
return prevUsed(current);
};
interval.end = item;
return interval;
};
interval.unshift = function (item) {
var prevStart = interval.start;
var prevUsed = interval.usedNext;
interval.isDone = false;
interval.start = item;
interval.current = item;
interval.usedNext = function (current) {
if (safeEquals(item, current)) {
return prevStart;
}
return prevUsed(current);
};
return interval;
};
interval.filter = function (by) {
var prevUsed = interval.usedNext;
interval.usedNext = function (current) {
var val = prevUsed(current);
if (by(val)) {
return val;
}
return interval.usedNext(val);
};
var nextStart = interval.start;
while (!by(nextStart)) {
nextStart = prevUsed(nextStart);
if (less(interval.end, nextStart)) {
interval.isDone = true;
return interval;
}
}
interval.start = nextStart;
return interval;
};
interval.shuffle = function () {
var acc = [];
var orig = interval.array();
while (orig.length !== 0) {
var index = Math.floor(Math.random() * (orig.length - 1));
acc.push.apply(acc, orig.splice(index, 1));
}
return acc;
};
return interval;
};
return generalInterval;
};