browser-tabs-lock
Advanced tools
Comparing version 1.2.15 to 1.3.0
@@ -7,2 +7,5 @@ # Changelog | ||
## [1.3.0] - 2023-04-25 | ||
- Allows passing of custom storage handler which can be used to override the fact that this lib writes to localstorage | ||
## [1.2.15] - 2021-08-09 | ||
@@ -9,0 +12,0 @@ |
@@ -0,1 +1,16 @@ | ||
export declare type StorageHandler = { | ||
key: (index: number) => Promise<string | null>; | ||
getItem: (key: string) => Promise<string | null>; | ||
clear: () => Promise<void>; | ||
removeItem: (key: string) => Promise<void>; | ||
setItem: (key: string, value: string) => Promise<void>; | ||
/** | ||
* Sync versions of the storage functions | ||
*/ | ||
keySync: (index: number) => string | null; | ||
getItemSync: (key: string) => string | null; | ||
clearSync: () => void; | ||
removeItemSync: (key: string) => void; | ||
setItemSync: (key: string, value: string) => void; | ||
}; | ||
export default class SuperTokensLock { | ||
@@ -5,3 +20,4 @@ private static waiters; | ||
private acquiredIatSet; | ||
constructor(); | ||
private storageHandler; | ||
constructor(storageHandler?: StorageHandler); | ||
/** | ||
@@ -8,0 +24,0 @@ * @async |
120
index.js
@@ -37,2 +37,3 @@ "use strict"; | ||
}; | ||
var _this = this; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -57,2 +58,44 @@ var processLock_1 = require("./processLock"); | ||
var LOCK_STORAGE_KEY = 'browser-tabs-lock-key'; | ||
var DEFAULT_STORAGE_HANDLER = { | ||
key: function (index) { return __awaiter(_this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
throw new Error("Unsupported"); | ||
}); | ||
}); }, | ||
getItem: function (key) { return __awaiter(_this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
throw new Error("Unsupported"); | ||
}); | ||
}); }, | ||
clear: function () { return __awaiter(_this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, window.localStorage.clear()]; | ||
}); | ||
}); }, | ||
removeItem: function (key) { return __awaiter(_this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
throw new Error("Unsupported"); | ||
}); | ||
}); }, | ||
setItem: function (key, value) { return __awaiter(_this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
throw new Error("Unsupported"); | ||
}); | ||
}); }, | ||
keySync: function (index) { | ||
return window.localStorage.key(index); | ||
}, | ||
getItemSync: function (key) { | ||
return window.localStorage.getItem(key); | ||
}, | ||
clearSync: function () { | ||
return window.localStorage.clear(); | ||
}, | ||
removeItemSync: function (key) { | ||
return window.localStorage.removeItem(key); | ||
}, | ||
setItemSync: function (key, value) { | ||
return window.localStorage.setItem(key, value); | ||
}, | ||
}; | ||
/** | ||
@@ -90,4 +133,5 @@ * @function delay | ||
var SuperTokensLock = /** @class */ (function () { | ||
function SuperTokensLock() { | ||
function SuperTokensLock(storageHandler) { | ||
this.acquiredIatSet = new Set(); | ||
this.storageHandler = undefined; | ||
this.id = getLockId(); | ||
@@ -99,2 +143,3 @@ this.acquireLock = this.acquireLock.bind(this); | ||
this.refreshLockWhileAcquired = this.refreshLockWhileAcquired.bind(this); | ||
this.storageHandler = storageHandler; | ||
if (SuperTokensLock.waiters === undefined) { | ||
@@ -117,3 +162,3 @@ SuperTokensLock.waiters = []; | ||
return __awaiter(this, void 0, void 0, function () { | ||
var iat, MAX_TIME, STORAGE_KEY, STORAGE, lockObj, TIMEOUT_KEY, lockObjPostDelay; | ||
var iat, MAX_TIME, STORAGE_KEY, STORAGE, lockObj, TIMEOUT_KEY, lockObjPostDelay, parsedLockObjPostDelay; | ||
return __generator(this, function (_a) { | ||
@@ -125,3 +170,3 @@ switch (_a.label) { | ||
STORAGE_KEY = LOCK_STORAGE_KEY + "-" + lockKey; | ||
STORAGE = window.localStorage; | ||
STORAGE = this.storageHandler === undefined ? DEFAULT_STORAGE_HANDLER : this.storageHandler; | ||
_a.label = 1; | ||
@@ -133,3 +178,3 @@ case 1: | ||
_a.sent(); | ||
lockObj = STORAGE.getItem(STORAGE_KEY); | ||
lockObj = STORAGE.getItemSync(STORAGE_KEY); | ||
if (!(lockObj === null)) return [3 /*break*/, 5]; | ||
@@ -142,3 +187,3 @@ TIMEOUT_KEY = this.id + "-" + lockKey + "-" + iat; | ||
_a.sent(); | ||
STORAGE.setItem(STORAGE_KEY, JSON.stringify({ | ||
STORAGE.setItemSync(STORAGE_KEY, JSON.stringify({ | ||
id: this.id, | ||
@@ -153,6 +198,6 @@ iat: iat, | ||
_a.sent(); // this is to prevent race conditions. This time must be more than the time it takes for storage.setItem | ||
lockObjPostDelay = STORAGE.getItem(STORAGE_KEY); | ||
lockObjPostDelay = STORAGE.getItemSync(STORAGE_KEY); | ||
if (lockObjPostDelay !== null) { | ||
lockObjPostDelay = JSON.parse(lockObjPostDelay); | ||
if (lockObjPostDelay.id === this.id && lockObjPostDelay.iat === iat) { | ||
parsedLockObjPostDelay = JSON.parse(lockObjPostDelay); | ||
if (parsedLockObjPostDelay.id === this.id && parsedLockObjPostDelay.iat === iat) { | ||
this.acquiredIatSet.add(iat); | ||
@@ -165,3 +210,3 @@ this.refreshLockWhileAcquired(STORAGE_KEY, iat); | ||
case 5: | ||
SuperTokensLock.lockCorrector(); | ||
SuperTokensLock.lockCorrector(this.storageHandler === undefined ? DEFAULT_STORAGE_HANDLER : this.storageHandler); | ||
return [4 /*yield*/, this.waitForSomethingToChange(MAX_TIME)]; | ||
@@ -184,3 +229,3 @@ case 6: | ||
setTimeout(function () { return __awaiter(_this, void 0, void 0, function () { | ||
var STORAGE, lockObj; | ||
var STORAGE, lockObj, parsedLockObj; | ||
return __generator(this, function (_a) { | ||
@@ -195,8 +240,8 @@ switch (_a.label) { | ||
} | ||
STORAGE = window.localStorage; | ||
lockObj = STORAGE.getItem(storageKey); | ||
STORAGE = this.storageHandler === undefined ? DEFAULT_STORAGE_HANDLER : this.storageHandler; | ||
lockObj = STORAGE.getItemSync(storageKey); | ||
if (lockObj !== null) { | ||
lockObj = JSON.parse(lockObj); | ||
lockObj.timeRefreshed = Date.now(); | ||
STORAGE.setItem(storageKey, JSON.stringify(lockObj)); | ||
parsedLockObj = JSON.parse(lockObj); | ||
parsedLockObj.timeRefreshed = Date.now(); | ||
STORAGE.setItemSync(storageKey, JSON.stringify(parsedLockObj)); | ||
processLock_1.default().unlock(iat); | ||
@@ -240,3 +285,3 @@ } | ||
else { | ||
resolve(); | ||
resolve(null); | ||
} | ||
@@ -302,20 +347,20 @@ } | ||
return __awaiter(this, void 0, void 0, function () { | ||
var STORAGE, STORAGE_KEY, lockObj; | ||
var STORAGE, STORAGE_KEY, lockObj, parsedlockObj; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
STORAGE = window.localStorage; | ||
STORAGE = this.storageHandler === undefined ? DEFAULT_STORAGE_HANDLER : this.storageHandler; | ||
STORAGE_KEY = LOCK_STORAGE_KEY + "-" + lockKey; | ||
lockObj = STORAGE.getItem(STORAGE_KEY); | ||
lockObj = STORAGE.getItemSync(STORAGE_KEY); | ||
if (lockObj === null) { | ||
return [2 /*return*/]; | ||
} | ||
lockObj = JSON.parse(lockObj); | ||
if (!(lockObj.id === this.id)) return [3 /*break*/, 2]; | ||
return [4 /*yield*/, processLock_1.default().lock(lockObj.iat)]; | ||
parsedlockObj = JSON.parse(lockObj); | ||
if (!(parsedlockObj.id === this.id)) return [3 /*break*/, 2]; | ||
return [4 /*yield*/, processLock_1.default().lock(parsedlockObj.iat)]; | ||
case 1: | ||
_a.sent(); | ||
this.acquiredIatSet.delete(lockObj.iat); | ||
STORAGE.removeItem(STORAGE_KEY); | ||
processLock_1.default().unlock(lockObj.iat); | ||
this.acquiredIatSet.delete(parsedlockObj.iat); | ||
STORAGE.removeItemSync(STORAGE_KEY); | ||
processLock_1.default().unlock(parsedlockObj.iat); | ||
SuperTokensLock.notifyWaiters(); | ||
@@ -334,6 +379,15 @@ _a.label = 2; | ||
*/ | ||
SuperTokensLock.lockCorrector = function () { | ||
SuperTokensLock.lockCorrector = function (storageHandler) { | ||
var MIN_ALLOWED_TIME = Date.now() - 5000; | ||
var STORAGE = window.localStorage; | ||
var KEYS = Object.keys(STORAGE); | ||
var STORAGE = storageHandler; | ||
var KEYS = []; | ||
var currIndex = 0; | ||
while (true) { | ||
var key = STORAGE.keySync(currIndex); | ||
if (key === null) { | ||
break; | ||
} | ||
KEYS.push(key); | ||
currIndex++; | ||
} | ||
var notifyWaiters = false; | ||
@@ -343,8 +397,8 @@ for (var i = 0; i < KEYS.length; i++) { | ||
if (LOCK_KEY.includes(LOCK_STORAGE_KEY)) { | ||
var lockObj = STORAGE.getItem(LOCK_KEY); | ||
var lockObj = STORAGE.getItemSync(LOCK_KEY); | ||
if (lockObj !== null) { | ||
lockObj = JSON.parse(lockObj); | ||
if ((lockObj.timeRefreshed === undefined && lockObj.timeAcquired < MIN_ALLOWED_TIME) || | ||
(lockObj.timeRefreshed !== undefined && lockObj.timeRefreshed < MIN_ALLOWED_TIME)) { | ||
STORAGE.removeItem(LOCK_KEY); | ||
var parsedlockObj = JSON.parse(lockObj); | ||
if ((parsedlockObj.timeRefreshed === undefined && parsedlockObj.timeAcquired < MIN_ALLOWED_TIME) || | ||
(parsedlockObj.timeRefreshed !== undefined && parsedlockObj.timeRefreshed < MIN_ALLOWED_TIME)) { | ||
STORAGE.removeItemSync(LOCK_KEY); | ||
notifyWaiters = true; | ||
@@ -351,0 +405,0 @@ } |
{ | ||
"name": "browser-tabs-lock", | ||
"version": "1.2.15", | ||
"version": "1.3.0", | ||
"description": "provides locking mechanism to sync across browser tabs", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
35366
548
1