2022-08-18 18:38:42 +03:00
|
|
|
/**
|
|
|
|
* @typedef {Object} UrlHistoryItem
|
2022-09-14 22:50:54 +03:00
|
|
|
* @prop {string} [path]
|
|
|
|
* @prop {string} [id]
|
|
|
|
* @prop {string} [type]
|
2022-09-19 09:45:52 +03:00
|
|
|
* @prop {string} [refSource]
|
|
|
|
* @prop {string} [refMedium]
|
|
|
|
* @prop {string} [refUrl]
|
2022-08-18 18:38:42 +03:00
|
|
|
* @prop {number} time
|
|
|
|
*/
|
|
|
|
|
2022-08-25 19:21:08 +03:00
|
|
|
/**
|
|
|
|
* @typedef {UrlHistoryItem[]} UrlHistoryArray
|
|
|
|
*/
|
|
|
|
|
2022-09-14 22:50:54 +03:00
|
|
|
/**
|
|
|
|
* Types allowed to add in the URLHistory manually
|
|
|
|
*/
|
|
|
|
const ALLOWED_TYPES = ['post'];
|
|
|
|
|
2022-08-18 18:38:42 +03:00
|
|
|
/**
|
|
|
|
* Represents a validated history
|
|
|
|
*/
|
|
|
|
class UrlHistory {
|
2022-08-25 19:21:08 +03:00
|
|
|
/**
|
|
|
|
* @private
|
|
|
|
* @param {UrlHistoryArray} urlHistory
|
|
|
|
*/
|
2022-08-18 18:38:42 +03:00
|
|
|
constructor(urlHistory) {
|
2022-08-25 19:21:08 +03:00
|
|
|
/** @private */
|
|
|
|
this.history = urlHistory;
|
2022-08-18 18:38:42 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
get length() {
|
|
|
|
return this.history.length;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Iterate from latest item to newest item (reversed!)
|
|
|
|
*/
|
|
|
|
*[Symbol.iterator]() {
|
|
|
|
yield* this.history.slice().reverse();
|
|
|
|
}
|
|
|
|
|
2022-08-25 19:21:08 +03:00
|
|
|
/**
|
|
|
|
* @private
|
|
|
|
* @param {any[]} history
|
|
|
|
* @returns {boolean}
|
|
|
|
*/
|
2022-08-18 18:38:42 +03:00
|
|
|
static isValidHistory(history) {
|
2022-08-25 19:21:08 +03:00
|
|
|
for (const item of history) {
|
2022-09-14 22:50:54 +03:00
|
|
|
const isValidIdEntry = typeof item?.id === 'string' && typeof item?.type === 'string' && ALLOWED_TYPES.includes(item.type);
|
|
|
|
const isValidPathEntry = typeof item?.path === 'string';
|
|
|
|
|
|
|
|
const isValidEntry = isValidPathEntry || isValidIdEntry;
|
|
|
|
|
|
|
|
if (!isValidEntry || !Number.isSafeInteger(item?.time)) {
|
2022-08-25 19:21:08 +03:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
2022-08-18 18:38:42 +03:00
|
|
|
}
|
|
|
|
|
2022-08-25 19:21:08 +03:00
|
|
|
/**
|
|
|
|
* @param {unknown} urlHistory
|
|
|
|
* @returns {UrlHistory}
|
|
|
|
*/
|
|
|
|
static create(urlHistory) {
|
|
|
|
if (!Array.isArray(urlHistory)) {
|
|
|
|
return new UrlHistory([]);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!this.isValidHistory(urlHistory)) {
|
|
|
|
return new UrlHistory([]);
|
|
|
|
}
|
|
|
|
|
2022-08-25 19:21:41 +03:00
|
|
|
const now = Date.now();
|
|
|
|
const filteredHistory = urlHistory.filter((item) => {
|
|
|
|
return now - item.time < this.MAX_AGE;
|
|
|
|
});
|
|
|
|
|
|
|
|
return new UrlHistory(filteredHistory);
|
2022-08-18 18:38:42 +03:00
|
|
|
}
|
2022-08-25 19:21:41 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
static MAX_AGE = 1000 * 60 * 60 * 24;
|
2022-08-18 18:38:42 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = UrlHistory;
|