license import { IDBPDatabase , IDBPTransaction , StoreNames } from 'idb' ; import BooksDb , { BooksDbBookData } from '../books-db' ; import BooksDbV2 from './books-db-v2' ; export default async function upgradeBooksDbFromV2 ( oldDb , oldVersion , newVersion , transaction ) { const dataStore = oldDb . createObjectStore ( 'data' , { keyPath : 'id' , autoIncrement : true , } ) ; dataStore . createIndex ( 'title' , 'title' ) ; oldDb . createObjectStore ( 'bookmark' , { keyPath : 'dataId' , } ) ; oldDb . createObjectStore ( 'lastItem' ) ; const oldDbV2 = oldDb as unknown as IDBPDatabase < BooksDbV2 > ; const transactionV2 = transaction as unknown as IDBPTransaction < BooksDbV2 > ; const oldValues = { data : { } , scrollX : { } , } ; { let cursor = await transactionV2 . objectStore ( 'keyvaluepairs' ) . openCursor ( ) ; while ( cursor ) { const regexResult = /([^-]+)-(.+)/ . exec ( cursor . key ) ; if ( regexResult ) { switch ( regexResult [ 1 ] ) { case 'data' : case 'scrollX' : oldValues [ regexResult [ 1 ] ] [ regexResult [ 2 ] ] = cursor . value ; break ; } } else if ( cursor . key === 'lastItem' ) { oldValues [ cursor . key ] = cursor . value ; } cursor = await cursor . continue ( ) ; } } await Promise . all ( Object . entries ( oldValues . data ) . map ( async ( [ key , valueString ] ) => { const parsedData = JSON . parse ( valueString ) ; if ( isFormattedDbV2Data ( parsedData ) ) { const bookDataWithoutKey = { ... parsedData , blobs : { } , hasThumb : false , } ; const dataId = await transaction . objectStore ( 'data' ) . add ( bookDataWithoutKey as BooksDbBookData ) ; const scrollX = oldValues . scrollX [ key ] ; if ( scrollX ) { await transaction . objectStore ( 'bookmark' ) . put ( { dataId , scrollX : + scrollX , progress : '0%' , } ) ; } if ( oldValues . lastItem === key ) { transaction . objectStore ( 'lastItem' ) . put ( { dataId , } , 0 ) ; } } } ) ) ; oldDbV2 . deleteObjectStore ( 'keyvaluepairs' ) ; oldDbV2 . deleteObjectStore ( 'local-forage-detect-blob-support' ) ; } interface DbV2Data { title : string ; elementHtml : string ; styleSheet : string ; } function isFormattedDbV2Data ( x ) { if ( typeof x === 'object' && x ) { for ( const key of [ 'title' , 'elementHtml' , 'styleSheet' ] ) { if ( ! ( key in x ) || typeof x [ key ] !== 'string' ) { return false ; } } return true ; } return false ; }