UNPKG

frail-map

Version:

FrailMap is an extension of WeakMap that supports primitive values using WeakRef.

121 lines (120 loc) 3.58 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.FrailMap = void 0; const StrongRef_js_1 = require("./StrongRef.js"); if (typeof WeakRef === "undefined") { console.warn(`WeakRef is not available at this environment, falling back to simple object references.`); } /** * Strong limbs with a weak grab, a WeakMap that supports scalars. * * `size` is not updated until a disposed object is accessed via one of * these methods: `has`, `get`, `entries`, `forEach`, `keys` or `values`. */ class FrailMap extends Map { constructor(entries) { super(); if (entries) { for (const [k, v] of entries) { this.set(k, v); } } } /** * Returns a specified element from the Map object. If the value that is * associated to the provided key is an object, then you will get a reference * to that object and any change made to that object will effectively modify * it inside the Map. * * @returns Returns the element associated with the specified key. If no * element is associated with the specified key or the value has been garbage * collected, undefined is returned. */ get(key) { const ref = super.get(key); const val = ref?.deref(); if (val === undefined) { this.delete(key); return; } return val.data; } /** * @returns boolean indicating whether an element with the specified key * exists or not, updates size if value has been garbage collected. */ has(key) { return super.has(key) && this.get(key) !== undefined; } /** * Adds a new element with a specified key and value to the Map. If an element * with the same key already exists, the element will be updated. * * A `strong` option can be provided to use a strong reference to act like a * normal map. */ set(key, value, options) { return super.set(key, (options?.strong || typeof WeakRef === "undefined" ? new StrongRef_js_1.StrongRef({ data: value }) : new WeakRef({ data: value }))); } /** * Executes a provided function once per each key/value pair in the Map, in * insertion order. */ forEach(callbackfn, thisArg) { super.forEach((container, k) => { const ref = container.deref(); if (ref !== undefined) { callbackfn.call(thisArg, ref.data, k, this); } else { this.delete(k); } }); } /** * Returns an iterable of key, value pairs for every entry in the map. */ entries() { const map = new Map(); this.forEach((v, k) => { map.set(k, v); }); return map.entries(); } /** * Returns an iterable of keys in the map */ keys() { const keys = new Set(); this.forEach((_, k) => { keys.add(k); }); return keys.values(); } /** * Returns an iterable of values in the map */ values() { const keys = new Set(); this.forEach((v) => { keys.add(v); }); return keys.values(); } [Symbol.iterator]() { return this.entries(); } get [Symbol.toStringTag]() { return "FrailMap"; } toJSON() { const json = {}; this.forEach((v, k) => { json[k] = v; }); return json; } } exports.FrailMap = FrailMap;