@thi.ng/associative
Version:
ES Map/Set-compatible implementations with customizable equality semantics & supporting operations
141 lines (140 loc) • 3.35 kB
JavaScript
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
};