UNPKG

tc39-weakrefs-shim

Version:
158 lines 5.36 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); // @ts-ignore const weak_tag_js_1 = __importDefault(require("@mhofman/weak-napi-native/weak-tag.js")); // @ts-ignore const object_info_js_1 = __importDefault(require("@mhofman/weak-napi-native/object-info.js")); const gc_js_1 = require("./gc.js"); exports.gc = gc_js_1.gc; const isObject_js_1 = __importDefault(require("../utils/lodash/isObject.js")); const setImmediate_js_1 = require("../utils/tasks/setImmediate.js"); const map = new WeakMap(); const registrations = new WeakMap(); function hasEmptyCell(context) { for (const info of context.cells.keys()) { if (!info.target) return true; } return false; } function* getEmptyCellEntries(context) { for (const [info, cell] of context.cells.entries()) { if (!context.cells) throw new TypeError(); if (info.target) continue; context.cells.delete(info); yield [info, cell]; } } function* getCellEntry(context) { const cell = context.cells.get(context.info); context.cells.delete(context.info); yield [context.info, cell]; } const CleanupIterator = function* CleanupIterator(entries) { for (const [info, cell] of entries) { if (cell.registrationSet) cell.registrationSet.delete(info); yield cell.holdings; } }; Object.defineProperty(Object.getPrototypeOf(CleanupIterator.prototype), Symbol.toStringTag, { value: "FinalizationGroup Cleanup Iterator", configurable: true, }); class FinalizationGroupNodeStub { constructor(cleanupCallback) { this.cleanupCallback = cleanupCallback; this.isCleanupJobActive = false; if (typeof cleanupCallback != "function") throw new TypeError(); const cells = (this.cells = new Map()); this.finalizedCallback = function () { if (!cells.get(this)) return; const context = { info: this, cells }; try { cleanupCallback(CleanupIterator(getCellEntry(context))); } catch (error) { setImmediate_js_1.setImmediate(() => { throw error; }); } context.info = context.cells = undefined; }; } register(target, holdings, unregisterToken = undefined) { if (!this.cells) throw new TypeError(); let tagSet = map.get(target); if (!tagSet) { tagSet = new Set(); map.set(target, tagSet); } if (target === holdings) throw new TypeError(); let registrationSet = unregisterToken ? registrations.get(unregisterToken) : undefined; if (!registrationSet && unregisterToken !== undefined) { if (!isObject_js_1.default(unregisterToken)) throw new TypeError(); registrationSet = new Set(); registrations.set(unregisterToken, registrationSet); } const info = new object_info_js_1.default(target, this.finalizedCallback); this.cells.set(info, { holdings, registrationSet, }); tagSet.add(new weak_tag_js_1.default(info)); if (registrationSet) registrationSet.add(info); } unregister(unregisterToken) { if (!this.cells) throw new TypeError(); const registrationSet = registrations.get(unregisterToken); if (!registrationSet) { if (!isObject_js_1.default(unregisterToken)) throw new TypeError(); return false; } let removed = false; for (const info of registrationSet) { const cell = this.cells.get(info); if (!cell) continue; this.cells.delete(info); registrationSet.delete(info); removed = true; } return removed; } cleanupSome(cleanupCallback = undefined) { if (!this.cells) throw new TypeError(); const context = { cells: this.cells }; const emptyObjectInfos = getEmptyCellEntries(context); if (this.isCleanupJobActive) throw new TypeError(); if (cleanupCallback === undefined) { cleanupCallback = this .cleanupCallback; } if (!hasEmptyCell(context)) { if (typeof cleanupCallback != "function") { throw new TypeError(); } return; } try { this.isCleanupJobActive = true; cleanupCallback(CleanupIterator(emptyObjectInfos)); } finally { context.cells = undefined; this.isCleanupJobActive = false; } } } exports.FinalizationGroup = FinalizationGroupNodeStub; class WeakRefNodeStub { constructor(target) { if (!isObject_js_1.default(target)) throw new TypeError(); this.info = new object_info_js_1.default(target, () => { }); } deref() { return this.info.target; } } exports.WeakRef = WeakRefNodeStub; //# sourceMappingURL=stub.js.map