UNPKG

@thi.ng/associative

Version:

ES Map/Set-compatible implementations with customizable equality semantics & supporting operations

141 lines (140 loc) 3.35 kB
var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __decorateClass = (decorators, target, key, kind) => { var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target; for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result; if (kind && result) __defProp(target, key, result); return result; }; import { SEMAPHORE } from "@thi.ng/api/api"; import { DCons } from "@thi.ng/dcons/dcons"; import { equiv } from "@thi.ng/equiv"; import { dissoc } from "./dissoc.js"; import { __equivSet } from "./internal/equiv.js"; import { __inspectable } from "./internal/inspect.js"; import { into } from "./into.js"; const __private = /* @__PURE__ */ new WeakMap(); const __vals = (inst) => __private.get(inst).vals; let LLSet = class extends Set { constructor(vals, opts = {}) { super(); __private.set(this, { equiv: opts.equiv || equiv, vals: new DCons() }); vals && this.into(vals); } *[Symbol.iterator]() { yield* __vals(this); } get [Symbol.species]() { return LLSet; } get [Symbol.toStringTag]() { return "LLSet"; } get size() { return __vals(this).length; } copy() { const s = new LLSet(null, this.opts()); __private.get(s).vals = __vals(this).copy(); return s; } empty() { return new LLSet(null, this.opts()); } clear() { __vals(this).clear(); } first() { if (this.size) { return __vals(this).head.value; } } add(key) { !this.has(key) && __vals(this).push(key); return this; } into(keys) { return into(this, keys); } has(key) { return this.get(key, SEMAPHORE) !== SEMAPHORE; } /** * Returns the canonical (stored) value for `key`, if present. If * the set contains no equivalent for `key`, returns `notFound`. * * @param key - search key * @param notFound - default value */ get(key, notFound) { const { equiv: equiv2, vals } = __private.get(this); let i = vals.head; while (i) { if (equiv2(i.value, key)) { return i.value; } i = i.next; } return notFound; } delete(key) { const { equiv: equiv2, vals } = __private.get(this); let i = vals.head; while (i) { if (equiv2(i.value, key)) { vals.splice(i, 1); return true; } i = i.next; } return false; } disj(keys) { return dissoc(this, keys); } equiv(o) { return __equivSet(this, o); } /** * The value args given to the callback `fn` MUST be treated as * readonly/immutable. This could be enforced via TS, but would * break ES6 Set interface contract. * * @param fn - * @param thisArg - */ forEach(fn, thisArg) { let i = __vals(this).head; while (i) { fn.call(thisArg, i.value, i.value, this); i = i.next; } } *entries() { for (let v of __vals(this)) { yield [v, v]; } } *keys() { yield* __vals(this); } *values() { yield* __vals(this); } opts() { return { equiv: __private.get(this).equiv }; } }; LLSet = __decorateClass([ __inspectable ], LLSet); const defLLSet = (vals, opts) => new LLSet(vals, opts); export { LLSet, defLLSet };