UNPKG

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
"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; };