UNPKG

@segment/analytics-next

Version:

Analytics Next (aka Analytics 2.0) is the latest version of Segment’s JavaScript SDK - enabling you to send your data to any tool without having to learn, test, or use a new API every time.

105 lines 3.86 kB
import { __assign, __extends, __spreadArray } from "tslib"; import { PriorityQueue } from '.'; import { Context } from '../../core/context'; import { isBrowser } from '../../core/environment'; var loc = { getItem: function () { }, setItem: function () { }, removeItem: function () { }, }; try { loc = isBrowser() && window.localStorage ? window.localStorage : loc; } catch (err) { console.warn('Unable to access localStorage', err); } function persisted(key) { var items = loc.getItem(key); return (items ? JSON.parse(items) : []).map(function (p) { return new Context(p.event, p.id); }); } function persistItems(key, items) { var existing = persisted(key); var all = __spreadArray(__spreadArray([], items, true), existing, true); var merged = all.reduce(function (acc, item) { var _a; return __assign(__assign({}, acc), (_a = {}, _a[item.id] = item, _a)); }, {}); loc.setItem(key, JSON.stringify(Object.values(merged))); } function seen(key) { var stored = loc.getItem(key); return stored ? JSON.parse(stored) : {}; } function persistSeen(key, memory) { var stored = seen(key); loc.setItem(key, JSON.stringify(__assign(__assign({}, stored), memory))); } function remove(key) { loc.removeItem(key); } var now = function () { return new Date().getTime(); }; function mutex(key, onUnlock, attempt) { if (attempt === void 0) { attempt = 0; } var lockTimeout = 50; var lockKey = "persisted-queue:v1:".concat(key, ":lock"); var expired = function (lock) { return new Date().getTime() > lock; }; var rawLock = loc.getItem(lockKey); var lock = rawLock ? JSON.parse(rawLock) : null; var allowed = lock === null || expired(lock); if (allowed) { loc.setItem(lockKey, JSON.stringify(now() + lockTimeout)); onUnlock(); loc.removeItem(lockKey); return; } if (!allowed && attempt < 3) { setTimeout(function () { mutex(key, onUnlock, attempt + 1); }, lockTimeout); } else { console.error('Unable to retrieve lock'); } } var PersistedPriorityQueue = /** @class */ (function (_super) { __extends(PersistedPriorityQueue, _super); function PersistedPriorityQueue(maxAttempts, key) { var _this = _super.call(this, maxAttempts, []) || this; var itemsKey = "persisted-queue:v1:".concat(key, ":items"); var seenKey = "persisted-queue:v1:".concat(key, ":seen"); var saved = []; var lastSeen = {}; mutex(key, function () { try { saved = persisted(itemsKey); lastSeen = seen(seenKey); remove(itemsKey); remove(seenKey); _this.queue = __spreadArray(__spreadArray([], saved, true), _this.queue, true); _this.seen = __assign(__assign({}, lastSeen), _this.seen); } catch (err) { console.error(err); } }); window.addEventListener('pagehide', function () { // we deliberately want to use the less powerful 'pagehide' API to only persist on events where the analytics instance gets destroyed, and not on tab away. if (_this.todo > 0) { var items_1 = __spreadArray(__spreadArray([], _this.queue, true), _this.future, true); try { mutex(key, function () { persistItems(itemsKey, items_1); persistSeen(seenKey, _this.seen); }); } catch (err) { console.error(err); } } }); return _this; } return PersistedPriorityQueue; }(PriorityQueue)); export { PersistedPriorityQueue }; //# sourceMappingURL=persisted.js.map