UNPKG

lib0

Version:

> Monorepo of isomorphic utility functions

267 lines (243 loc) 4.77 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var _function = require('./function-314580f7.cjs'); var error = require('./error-0c1f634f.cjs'); var equality = require('./equality.cjs'); require('./array-78849c95.cjs'); require('./set-5b47859e.cjs'); require('./object-c0c9435b.cjs'); class ListNode { constructor () { /** * @type {this|null} */ this.next = null; /** * @type {this|null} */ this.prev = null; } } /** * @template {ListNode} N */ class List { constructor () { /** * @type {N | null} */ this.start = null; /** * @type {N | null} */ this.end = null; this.len = 0; } * [Symbol.iterator] () { let n = this.start; while (n) { yield n; n = n.next; } } toArray () { return map(this, _function.id) } /** * @param {function(N):any} f */ forEach (f) { forEach(this, f); } /** * @template M * @param {function(N):M} f * @return {Array<M>} */ map (f) { return map(this, f) } /** * @param {List<any>} other */ [equality.EqualityTraitSymbol] (other) { let n = this.start; let m = other.start; while (n && m) { if (!equality.equals(n, m)) return false n = n.next; m = m.next; } return n === m // only true iff n == null && m == null } } /** * @note The queue implementation is experimental and unfinished. * Don't use this in production yet. * * @template {ListNode} N * * @return {List<N>} */ const create = () => new List(); /** * @template {ListNode} N * * @param {List<N>} queue */ const isEmpty = queue => queue.start === null; /** * Remove a single node from the queue. Only works with Queues that operate on Doubly-linked lists of nodes. * * @template {ListNode} N * * @param {List<N>} list * @param {N} node */ const remove = (list, node) => { const prev = node.prev; const next = node.next; if (prev) { prev.next = next; } else { list.start = next; } if (next) { next.prev = prev; } else { list.end = prev; } list.len--; return node }; /** * @deprecated @todo remove in next major release */ const removeNode = remove; /** * @template {ListNode} N * * @param {List<N>} queue * @param {N| null} left * @param {N| null} right * @param {N} node */ const insertBetween = (queue, left, right, node) => { /* c8 ignore start */ if (left != null && left.next !== right) { throw error.unexpectedCase() } /* c8 ignore stop */ if (left) { left.next = node; } else { queue.start = node; } if (right) { right.prev = node; } else { queue.end = node; } node.prev = left; node.next = right; queue.len++; }; /** * Remove a single node from the queue. Only works with Queues that operate on Doubly-linked lists of nodes. * * @template {ListNode} N * * @param {List<N>} queue * @param {N} node * @param {N} newNode */ const replace = (queue, node, newNode) => { insertBetween(queue, node, node.next, newNode); remove(queue, node); }; /** * @template {ListNode} N * * @param {List<N>} queue * @param {N} n */ const pushEnd = (queue, n) => insertBetween(queue, queue.end, null, n); /** * @template {ListNode} N * * @param {List<N>} queue * @param {N} n */ const pushFront = (queue, n) => insertBetween(queue, null, queue.start, n); /** * @template {ListNode} N * * @param {List<N>} list * @return {N| null} */ const popFront = list => list.start ? removeNode(list, list.start) : null; /** * @template {ListNode} N * * @param {List<N>} list * @return {N| null} */ const popEnd = list => list.end ? removeNode(list, list.end) : null; /** * @template {ListNode} N * @template M * * @param {List<N>} list * @param {function(N):M} f * @return {Array<M>} */ const map = (list, f) => { /** * @type {Array<M>} */ const arr = []; let n = list.start; while (n) { arr.push(f(n)); n = n.next; } return arr }; /** * @template {ListNode} N * * @param {List<N>} list */ const toArray = list => map(list, _function.id); /** * @template {ListNode} N * @param {List<N>} list * @param {function(N):any} f */ const forEach = (list, f) => { let n = list.start; while (n) { f(n); n = n.next; } }; exports.List = List; exports.ListNode = ListNode; exports.create = create; exports.forEach = forEach; exports.insertBetween = insertBetween; exports.isEmpty = isEmpty; exports.map = map; exports.popEnd = popEnd; exports.popFront = popFront; exports.pushEnd = pushEnd; exports.pushFront = pushFront; exports.remove = remove; exports.removeNode = removeNode; exports.replace = replace; exports.toArray = toArray; //# sourceMappingURL=list.cjs.map