threaded-lock
Version:
A threaded lock for Javascript written in Typescript
98 lines (97 loc) • 3.25 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
var interval = 40;
var default_1 = (function () {
function default_1(name, timeout, seed) {
if (timeout === void 0) { timeout = 5000; }
this.name = name;
this.timeout = timeout;
this.seed = seed;
if (!this.seed) {
this.seed = Math.random();
}
this.setExpiration();
}
default_1.prototype.lock = function () {
var _this = this;
return new Promise(function (res, rej) {
_this.lockCheck = function () {
var doublecheck = _this.read();
if (doublecheck && doublecheck.expires > Date.now()) {
return;
}
if (_this.unlock()) {
res();
}
};
var existing = _this.read();
if (!existing || existing.expires < Date.now()) {
_this.write();
setTimeout(function () {
var doublecheck = _this.read();
var claimed = false;
if (doublecheck) {
if (doublecheck.seed === _this.seed || doublecheck.expires < Date.now()) {
claimed = true;
_this.claimLockFlow(res, rej);
return;
}
}
if (claimed) {
return;
}
_this.waitOnLockFlow();
}, interval);
return;
}
_this.waitOnLockFlow();
});
};
default_1.prototype.unlock = function () {
var lock = this.read();
if (lock && lock.seed !== this.seed && lock.expires > Date.now()) {
return false;
}
clearInterval(this.heartbeat);
window.removeEventListener("storage", this.lockCheck);
localStorage.removeItem(this.name);
return true;
};
default_1.prototype.read = function () {
var res = localStorage.getItem(this.name);
if (!res) {
return undefined;
}
try {
return JSON.parse(res);
}
catch (e) {
return undefined;
}
};
default_1.prototype.write = function () {
localStorage.setItem(this.name, JSON.stringify(this));
};
default_1.prototype.setExpiration = function () {
this.expires = Date.now() + this.timeout;
};
default_1.prototype.claimLockFlow = function (res, rej) {
var _this = this;
this.setExpiration();
window.removeEventListener("storage", this.lockCheck);
this.heartbeat = setInterval(function () {
_this.setExpiration();
_this.write();
}, this.timeout - this.timeout / 2);
res();
};
default_1.prototype.waitOnLockFlow = function () {
var _this = this;
window.addEventListener("storage", this.lockCheck);
this.heartbeat = setInterval(function () {
_this.lockCheck();
}, this.timeout);
};
return default_1;
}());
exports.default = default_1;