import StorageWrapper from './storage-wrapper'; import { Error, Utils, getLogger } from '@playkit-js/playkit-js'; import { KalturaPlayer } from '../../kaltura-player'; import { KalturaPlayerConfig } from '../../types'; export class BaseStorageHelper { public static instance: BaseStorageHelper | null = null; public storageManagers: Array; constructor() { this.storageManagers = []; } public addManager(manager: BaseStorageManager): void { this.storageManagers.push(manager); } public static getInstance(): BaseStorageHelper { if (this.instance === null) { this.instance = new BaseStorageHelper(); } return this.instance; } } export class BaseStorageManager { protected static _logger: any; public static StorageKeys: { [key: string]: string }; /** * Initializes class. * @private * @param {string} className - The manager's class name. * @returns {void} */ public static init(className: string): void { this._logger = getLogger(className); BaseStorageHelper.getInstance().addManager(this); } /** * Applies cache support if it's supported by the environment. * @private * @param {KalturaPlayer} player - The Kaltura player. * @returns {void} */ public static attachAll(player: KalturaPlayer): void { BaseStorageHelper.getInstance().storageManagers.forEach((manager: BaseStorageManager) => { // @ts-expect-error // does not exist on type - does not exist on type, Did you mean to access the static member 'BaseStorageManager.attach' instead? if (manager.isStorageAvailable()) { // @ts-expect-error // does not exist on type - does not exist on type, Did you mean to access the static member 'BaseStorageManager.attach' instead? manager.attach(player); } }); } /** * Sets the storage config on the player config if certain conditions are met. * @private * @param {KPOptionsObject} options - kaltura player options * @returns {void} */ public static setStorageConfig(options: KalturaPlayerConfig): void { BaseStorageHelper.getInstance().storageManagers.forEach((manager) => { // @ts-expect-error // does not exist on type - does not exist on type, Did you mean to access the static member 'BaseStorageManager.attach' instead? if (manager.isStorageAvailable() && manager.hasStorage()) { // @ts-expect-error // does not exist on type - does not exist on type, Did you mean to access the static member 'BaseStorageManager.attach' instead? Utils.Object.mergeDeep(options, manager.getStorageConfig()); } }); } /** * @static * @private * @returns {boolean} - Whether the storage is implemented in the current browser. */ public static isStorageAvailable(): boolean { return StorageWrapper.isStorageAvailable(this.getStorageObject()); } /** * Checks if we have previous storage. * @private * @static * @return {boolean} - Whether we have previous storage. */ public static hasStorage(): boolean { const storageSize = this.getStorageSize(); const hasStorage = storageSize !== 0; if (hasStorage) { this._logger.debug('Storage found with size of ', storageSize); } else { this._logger.debug('No storage found'); } return hasStorage; } /** * Sets an item in the storage. * @private * @static * @param {string} key - The key of the item * @param {any} item - The value of the item * @returns {void} */ public static setItem(key: string, item: any): void { StorageWrapper.setItem(key, item, this.getStorageObject()); } /** * Gets an item from the storage. * @private * @static * @param {string} key - The item key * @returns {any} - The item value */ public static getItem(key: string): any { return StorageWrapper.getItem(key, this.getStorageObject()); } /** * Gets the storage size * @static * @private * @return {number} - The number of keys in the local storage started with wanted prefix. */ public static getStorageSize(): number { return StorageWrapper.getStorageSize(this.getStorageObject()); } /** * Gets storage items * @param {Object} storage - The storage object to use. * @static * @private * @return {object} - The items that their keys in the storage starts with wanted prefix. */ public static getStorageItems(): number { return StorageWrapper.getStorageItems(this.getStorageObject()); } /** * Gets the storage in the structure of the player configuration. * @private * @static * @return {Object} - Partial storageable player configuration. */ public static getStorageConfig(): any { const values = this._getExistingValues(); const storageConfig = this._buildStorageConfig(values); this._logger.debug('Gets storage config', storageConfig); return storageConfig; } /** * Gets the current existing values in the storage. * @private * @static * @return {Object} - The values object from the storage. */ public static _getExistingValues(): any { const obj = {}; Object.keys(this.StorageKeys).forEach((key) => { const value = this.StorageKeys[key]; const item = this.getItem(value); // dont change to !==, it effects the logic // eslint-disable-next-line if (item != null) { obj[value] = item; } }); return obj; } /** * Builds the storage configuration object. * @private * @static * @param {Object} values - The values to set to storage configuration * @return {Object} - The configuration with values from the storage. */ public static _buildStorageConfig(values: any): any { const storageConfig = Utils.Object.mergeDeep({}, values); delete storageConfig.textStyle; return { playback: storageConfig }; } /** * Gets the storage object to access. * i.e: sessionStorage, localStorage * @private * @static * @return {Object} - The storage object. */ public static getStorageObject(): any { throw new Error(Error.Severity.CRITICAL, Error.Category.PLAYER, Error.Code.RUNTIME_ERROR_METHOD_NOT_IMPLEMENTED, 'getStorageObject()'); } /** * Attaches listeners to the storage manager. * @private * @static * @return {void} */ // eslint-disable-next-line @typescript-eslint/no-unused-vars public static attach(player: KalturaPlayer): void { throw new Error(Error.Severity.CRITICAL, Error.Category.PLAYER, Error.Code.RUNTIME_ERROR_METHOD_NOT_IMPLEMENTED, 'attach()'); } /** * Initialize the storage manager. * @private * @static * @return {void} */ public static initialize(): void { throw new Error(Error.Severity.CRITICAL, Error.Category.PLAYER, Error.Code.RUNTIME_ERROR_METHOD_NOT_IMPLEMENTED, 'initialize()'); } }