UNPKG

threaded-lock

Version:

A threaded lock for Javascript written in Typescript

98 lines (97 loc) 3.25 kB
"use strict"; 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;