UNPKG

@everwhen/temporal

Version:
70 lines (69 loc) 2.2 kB
/** * A series wraps a list of values that should be * treated with order, providing methods to navigate * and compare items within the series. */ export class Series { #items; #indexesByKey; #itemsByIndex; #toKey; constructor(items, toKey = (item) => `${item}`) { this.#items = items; this.#toKey = toKey; this.#indexesByKey = new Map(); this.#itemsByIndex = new Map(); items.forEach((item, idx) => { this.#indexesByKey.set(toKey(item), idx); this.#itemsByIndex.set(idx, item); }); } /** * Given two values in the series, returns the * value that occurs earlier in the series */ min(a, b) { const idxA = this.#indexesByKey.get(this.#toKey(a)) ?? 0; const idxB = this.#indexesByKey.get(this.#toKey(b)) ?? 0; return idxA < idxB ? a : b; } /** * Given two values in the series, returns the * value that occurs later in the series */ max(a, b) { const idxA = this.#indexesByKey.get(this.#toKey(a)) ?? 0; const idxB = this.#indexesByKey.get(this.#toKey(b)) ?? 0; return idxA > idxB ? a : b; } /** * Returns the first item from the series */ first() { return this.#itemsByIndex.get(0); } /** * Returns the last item in the series */ last() { return this.#itemsByIndex.get(this.#items.length - 1); } /** * Given an item in the series returns the next item * in the series or default if the given value is * the last item in the series */ next(current, defaultValue) { const currentIdx = this.#indexesByKey.get(this.#toKey(current)) ?? -1; return (this.#itemsByIndex.get(currentIdx + 1) ?? defaultValue ?? this.first()); } /** * Given an item in the series returns the previous item * in the series or default if the given value is * the first item in the series */ previous(current, defaultValue) { const currentIdx = this.#indexesByKey.get(this.#toKey(current)) ?? 0; return this.#itemsByIndex.get(currentIdx - 1) ?? defaultValue ?? this.last(); } }