import type { SelectionManager , SelectionsBackup , } from '../Selection/SelectionManager' ; import { decycle , isPlainObject , retrocycle } from '../Utils' ; import type { CacheInstance } from './dataCache' ; export interface PersistenceHelpers { backupPersistence ( version ? ) : string ; restorePersistence ( backup , expectedVersion ? ) : Promise < boolean > ; restorePersistence ( backup , expectedVersion ? ) : boolean ; } export function createPersistenceHelpers ( clientCache , selectionManager ) { function backupPersistence ( version ? ) { const { query } = clientCache . cache ; const cache = decycle ( { query } ) ; const selections = selectionManager . backup ( ) ; return JSON . stringify ( { version , cache , selections , } ) ; } function restorePersistence ( backup , expectedVersion ? ) ; function restorePersistence ( backup , expectedVersion ? ) ; function restorePersistence ( backup , expectedVersion ? ) { if ( typeof backup === 'function' ) { return new Promise ( ( resolve ) => { backup ( ) . then ( ( value ) => resolve ( restore ( value ) ) ) . catch ( ( ) => resolve ( false ) ) ; } ) ; } return restore ( backup ) ; function restore ( backup ? ) { if ( typeof backup !== 'string' ) return false ; const backupObject = JSON . parse ( backup ) ; if ( isPlainObject ( backupObject ) && isPlainObject ( backupObject . cache ) ) { if ( ( expectedVersion && ! backupObject . version ) || ( backupObject . version && ! expectedVersion ) ) { return false ; } if ( expectedVersion && backupObject . version ) { if ( typeof backupObject . version === 'string' ) { if ( backupObject . version !== expectedVersion ) { return false ; } } else { return false ; } } Object . assign ( clientCache . cache , retrocycle ( backupObject . cache ) ) ; selectionManager . restore ( backupObject . selections ) ; return true ; } return false ; } } return { backupPersistence , restorePersistence , } ; }