UNPKG

@thi.ng/associative

Version:

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

155 lines (154 loc) 3.95 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 { isPlainObject } from "@thi.ng/checks/is-plain-object"; import { equiv } from "@thi.ng/equiv"; import { pairs } from "@thi.ng/transducers/pairs"; import { ArraySet } from "./array-set.js"; import { dissoc } from "./dissoc.js"; import { __equivMap } from "./internal/equiv.js"; import { __inspectable } from "./internal/inspect.js"; import { into } from "./into.js"; const __private = /* @__PURE__ */ new WeakMap(); const __map = (map) => __private.get(map).map; let EquivMap = class extends Map { /** * Creates a new instance with optional initial key-value pairs and provided * options. If no `opts` are given, uses `ArraySet` for storing canonical * keys and * [`equiv`](https://docs.thi.ng/umbrella/equiv/functions/equiv.html) for * checking key equivalence. * * @param pairs - key-value pairs * @param opts - config options */ constructor(pairs2, opts) { super(); const _opts = { equiv, keys: ArraySet, ...opts }; __private.set(this, { keys: new _opts.keys(null, { equiv: _opts.equiv }), map: /* @__PURE__ */ new Map(), opts: _opts }); if (pairs2) { this.into(pairs2); } } [Symbol.iterator]() { return this.entries(); } get [Symbol.species]() { return EquivMap; } get [Symbol.toStringTag]() { return "EquivMap"; } get size() { return __private.get(this).keys.size; } clear() { const { keys, map } = __private.get(this); keys.clear(); map.clear(); } empty() { return new EquivMap(null, __private.get(this).opts); } copy() { const { keys, map, opts } = __private.get(this); const m = new EquivMap(); __private.set(m, { keys: keys.copy(), map: new Map(map), opts }); return m; } equiv(o) { return __equivMap(this, o); } delete(key) { const { keys, map } = __private.get(this); key = keys.get(key, SEMAPHORE); if (key !== SEMAPHORE) { map.delete(key); keys.delete(key); return true; } return false; } dissoc(keys) { return dissoc(this, keys); } /** * The key & value args given the callback `fn` MUST be treated as * readonly/immutable. This could be enforced via TS, but would * break ES6 Map interface contract. * * @param fn - * @param thisArg - */ forEach(fn, thisArg) { for (let pair of __map(this)) { fn.call(thisArg, pair[1], pair[0], this); } } get(key, notFound) { const { keys, map } = __private.get(this); key = keys.get(key, SEMAPHORE); if (key !== SEMAPHORE) { return map.get(key); } return notFound; } has(key) { return __private.get(this).keys.has(key); } set(key, value) { const { keys, map } = __private.get(this); const k = keys.get(key, SEMAPHORE); if (k !== SEMAPHORE) { map.set(k, value); } else { keys.add(key); map.set(key, value); } return this; } into(pairs2) { return into(this, pairs2); } entries() { return __map(this).entries(); } keys() { return __map(this).keys(); } values() { return __map(this).values(); } opts() { return __private.get(this).opts; } }; EquivMap = __decorateClass([ __inspectable ], EquivMap); function defEquivMap(src, opts) { return new EquivMap( isPlainObject(src) ? pairs(src) : src, opts ); } export { EquivMap, defEquivMap };