/** * External dependencies */ import type { eventWithTime } from '@rrweb/types'; const DB_NAME = 'neliosr-events'; const DB_VERSION = 1; const DB_STORE_NAME = 'events'; let db: IDBDatabase | undefined; export type StoredEvent = { readonly id: number; readonly event: eventWithTime; }; export const initEventsStore = ( callback: () => void ): void => { const req = indexedDB.open( DB_NAME, DB_VERSION ); req.onupgradeneeded = function ( event: IDBVersionChangeEvent ) { db = ( event.target as IDBOpenDBRequest ).result; if ( ! db.objectStoreNames.contains( DB_STORE_NAME ) ) { db.createObjectStore( DB_STORE_NAME, { keyPath: 'id', autoIncrement: true, } ); } }; req.onerror = function ( event ) { // eslint-disable-next-line no-console console.error( 'initEventsStore:', ( event.target as unknown as { errorCode: unknown } ).errorCode ); }; req.onsuccess = function ( event ) { db = ( event.target as IDBOpenDBRequest ).result; callback(); }; }; function getObjectStore( storeName: string, mode: IDBTransactionMode ) { if ( ! db ) { return undefined; } try { const tx = db.transaction( storeName, mode ); return tx.objectStore( storeName ); // eslint-disable-next-line @typescript-eslint/no-unused-vars } catch ( _ ) { return undefined; } } //end getObjectStore() export const clearEventsStore = (): void => { const store = getObjectStore( DB_STORE_NAME, 'readwrite' ); if ( ! store ) { return; } const req = store.clear(); req.onerror = function ( event ) { // eslint-disable-next-line no-console console.error( 'clearObjectStore:', ( event.target as unknown as { errorCode: unknown } ).errorCode ); }; }; //end clearEventsStore() export const saveEvent = ( event: eventWithTime ): void => { const store = getObjectStore( DB_STORE_NAME, 'readwrite' ); if ( ! store ) { return; } const req = store.add( event ); req.onerror = function () { // eslint-disable-next-line no-console console.error( 'saveEvent error', this.error ); }; }; export const saveEvents = ( events: ReadonlyArray< eventWithTime > ): void => { const store = getObjectStore( DB_STORE_NAME, 'readwrite' ); if ( ! store || ! events.length ) { return; } //end if events.forEach( ( event ) => { const req = store.add( event ); req.onerror = function () { // eslint-disable-next-line no-console console.error( 'saveEvents error', this.error ); }; } ); }; export const peekEvents = ( callback: ( events: ReadonlyArray< StoredEvent > ) => void ): void => { const store = getObjectStore( DB_STORE_NAME, 'readonly' ); if ( ! store ) { return; } const events: StoredEvent[] = []; const req = store.openCursor(); req.onsuccess = ( event ) => { const cursor = ( event.target as unknown as { result: IDBCursor; } ).result; if ( cursor ) { events.push( { id: cursor.primaryKey as number, event: ( cursor as unknown as { value: eventWithTime } ).value, } ); cursor.continue(); } else { callback( events ); } //end if }; req.onerror = function () { // eslint-disable-next-line no-console console.error( 'getEvents error', this.error ); }; }; export const removeEvents = ( ids: ReadonlyArray< number > ): void => { const store = getObjectStore( DB_STORE_NAME, 'readwrite' ); if ( ! store || ! ids.length ) { return; } //end if ids.forEach( ( id ) => { const req = store.delete( id ); req.onerror = function () { // eslint-disable-next-line no-console console.error( 'removeEvents error', this.error ); }; } ); };