function noop() { } const defaultDispose = noop; const _WeakRef = typeof WeakRef !== "undefined" ? WeakRef : function (value) { return { deref: () => value }; }; const _WeakMap = typeof WeakMap !== "undefined" ? WeakMap : Map; const _FinalizationRegistry = typeof FinalizationRegistry !== "undefined" ? FinalizationRegistry : function () { return { register: noop, unregister: noop, }; }; const finalizationBatchSize = 10024; export class WeakCache { constructor(max = Infinity, dispose = defaultDispose) { this.max = max; this.dispose = dispose; this.map = new _WeakMap(); this.newest = null; this.oldest = null; this.unfinalizedNodes = new Set(); this.finalizationScheduled = false; this.size = 0; this.finalize = () => { const iterator = this.unfinalizedNodes.values(); for (let i = 0; i < finalizationBatchSize; i++) { const node = iterator.next().value; if (!node) break; this.unfinalizedNodes.delete(node); const key = node.key; delete node.key; node.keyRef = new _WeakRef(key); this.registry.register(key, node, node); } if (this.unfinalizedNodes.size > 0) { queueMicrotask(this.finalize); } else { this.finalizationScheduled = false; } }; this.registry = new _FinalizationRegistry(this.deleteNode.bind(this)); } has(key) { return this.map.has(key); } get(key) { const node = this.getNode(key); return node && node.value; } getNode(key) { const node = this.map.get(key); if (node && node !== this.newest) { const { older, newer } = node; if (newer) { newer.older = older; } if (older) { older.newer = newer; } node.older = this.newest; node.older.newer = node; node.newer = null; this.newest = node; if (node === this.oldest) { this.oldest = newer; } } return node; } set(key, value) { let node = this.getNode(key); if (node) { return (node.value = value); } node = { key, value, newer: null, older: this.newest, }; if (this.newest) { this.newest.newer = node; } this.newest = node; this.oldest = this.oldest || node; this.scheduleFinalization(node); this.map.set(key, node); this.size++; return node.value; } clean() { while (this.oldest && this.size > this.max) { this.deleteNode(this.oldest); } } deleteNode(node) { if (node === this.newest) { this.newest = node.older; } if (node === this.oldest) { this.oldest = node.newer; } if (node.newer) { node.newer.older = node.older; } if (node.older) { node.older.newer = node.newer; } this.size--; const key = node.key || (node.keyRef && node.keyRef.deref()); this.dispose(node.value, key); if (!node.keyRef) { this.unfinalizedNodes.delete(node); } else { this.registry.unregister(node); } if (key) this.map.delete(key); } delete(key) { const node = this.map.get(key); if (node) { this.deleteNode(node); return true; } return false; } scheduleFinalization(node) { this.unfinalizedNodes.add(node); if (!this.finalizationScheduled) { this.finalizationScheduled = true; queueMicrotask(this.finalize); } } } //# sourceMappingURL=weak.js.map