extract-base-iterator
Version:
Base iterator for extract iterators like tar-iterator and zip-iterator
95 lines • 3.36 kB
JavaScript
/**
* Lock - Reference counting for iterator lifecycle
*
* Ensures the iterator doesn't complete until all entries have been processed.
* Uses cleanup registration pattern so each iterator can register its specific
* cleanup functions (e.g., close file descriptors, delete temp files, end parsers).
*
* Usage:
* const lock = new Lock();
* lock.onDestroy = (err) => BaseIterator.prototype.end.call(this, err);
* lock.registerCleanup(() => { this.extract.end(); });
* lock.registerCleanup(() => { fs.unlinkSync(this.tempPath); });
*
* // For each entry:
* lock.retain();
* // ... when entry is consumed:
* lock.release();
*
* // When iteration complete:
* lock.err = err; // optional error
* lock.release(); // Initial count
*/ "use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "default", {
enumerable: true,
get: function() {
return Lock;
}
});
function _class_call_check(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
var Lock = /*#__PURE__*/ function() {
"use strict";
function Lock() {
_class_call_check(this, Lock);
this.count = 1;
this.cleanupFns = [];
/** Error to pass to onDestroy callback */ this.err = null;
/** Called after all cleanups when count reaches 0 */ this.onDestroy = null;
}
var _proto = Lock.prototype;
/**
* Register a cleanup function to be called when the lock is destroyed.
* Cleanup functions are called in registration order, before onDestroy.
* @param fn Cleanup function (should not throw)
*/ _proto.registerCleanup = function registerCleanup(fn) {
this.cleanupFns.push(fn);
};
/**
* Increment reference count.
* Call when starting to process a new entry.
*/ _proto.retain = function retain() {
this.count++;
};
/**
* Decrement reference count.
* Call when an entry has been fully consumed.
* When count reaches 0, cleanup is triggered.
*/ _proto.release = function release() {
if (this.count <= 0) {
throw new Error('Lock count is corrupted');
}
this.count--;
if (this.count === 0) {
this._destroy();
}
};
/**
* Internal cleanup - called when reference count reaches 0
*/ _proto._destroy = function _destroy() {
// Run all registered cleanup functions in order
// Note: Use traditional for loop for Node 0.8 compatibility (no Symbol.iterator)
var fns = this.cleanupFns;
for(var i = 0; i < fns.length; i++){
try {
fns[i]();
} catch (_e) {
// Ignore cleanup errors to ensure all cleanup runs
}
}
this.cleanupFns = [];
// Call onDestroy callback LAST (typically calls iterator.end())
if (this.onDestroy) {
this.onDestroy(this.err);
this.onDestroy = null;
}
};
return Lock;
}();
/* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; }