import { AppStorageUsage } from "./models/app-storage-usage.model" ; import * as _ from "lodash" ; import { BrowserStorageType } from "./models/browser-storage-type.enum" ; export class BrowserStorage { constructor ( extensionId ? ) { this . extensionId = ( extensionId ) ? extensionId : null ; } public static readonly ON_GET_MESSAGE : string = "ON_GET_MESSAGE" ; public static readonly ON_SET_MESSAGE : string = "ON_SET_MESSAGE" ; public static readonly ON_RM_MESSAGE : string = "ON_RM_MESSAGE" ; public static readonly ON_CLEAR_MESSAGE : string = "ON_CLEAR_MESSAGE" ; public static readonly ON_USAGE_MESSAGE : string = "ON_USAGE_MESSAGE" ; private static instance : BrowserStorage = null ; private extensionId : string = null ; public static getInstance ( ) { if ( ! this . instance ) { this . instance = new BrowserStorage ( ( chrome && chrome . runtime && chrome . runtime . id ) ? chrome . runtime . id : null ) ; } return this . instance ; } public setExtensionId ( extensionId ) { this . extensionId = ( extensionId ) ? extensionId : null ; } public hasExtensionId ( ) { return ( this . extensionId !== null ) ; } param storageType param key public get < T > ( storageType , key ? ) { this . verifyExtensionId ( ) ; key = ( ! key ) ? null : key ; return new Promise < T > ( ( resolve , reject ) => { if ( this . hasStorageAccess ( ) ) { chrome . storage [ storageType ] . get ( key , ( result ) => { const error = chrome . runtime . lastError ; if ( error ) { reject ( error . message ) ; } else { if ( ! key ) { resolve ( result ) ; } else { resolve ( result [ key ] ) ; } } } ) ; } else { this . backgroundStorageQuery < T > ( BrowserStorage . ON_GET_MESSAGE , storageType , key ) . then ( ( result ) => { resolve ( result ) ; } ) ; } } ) ; } param storageType param key param value public set < T > ( storageType , key , value ) { this . verifyExtensionId ( ) ; return new Promise < void > ( ( resolve , reject ) => { if ( this . hasStorageAccess ( ) ) { let object = { } ; if ( key ) { object [ key ] = value ; } else { object = value ; } chrome . storage [ storageType ] . set ( object , ( ) => { const error = chrome . runtime . lastError ; if ( error ) { reject ( error . message ) ; } else { resolve ( ) ; } } ) ; } else { this . backgroundStorageQuery < T > ( BrowserStorage . ON_SET_MESSAGE , storageType , key , value ) . then ( ( ) => { resolve ( ) ; } ) ; } } ) ; } param storageType param path param value public upsertProperty < T , V > ( storageType , path , value ) { const key = path . shift ( ) ; return this . get < T > ( storageType , key ) . then ( ( result ) => { result = ( path . length > 0 ) ? ( _ . set ( result as Object , path , value ) as T ) : ( value as any ) ; return this . set < T > ( storageType , key , result ) ; } ) ; } param storageType param key public rm < T > ( storageType , key ) { this . verifyExtensionId ( ) ; return new Promise < void > ( ( resolve , reject ) => { if ( this . hasStorageAccess ( ) ) { chrome . storage [ storageType ] . remove ( < any > key , ( ) => { const error = chrome . runtime . lastError ; if ( error ) { reject ( error . message ) ; } else { resolve ( ) ; } } ) ; } else { this . backgroundStorageQuery < T > ( BrowserStorage . ON_RM_MESSAGE , storageType , key ) . then ( ( ) => { resolve ( ) ; } ) ; } } ) ; } param storageType public clear < T > ( storageType ) { this . verifyExtensionId ( ) ; return new Promise < void > ( ( resolve , reject ) => { if ( this . hasStorageAccess ( ) ) { chrome . storage [ storageType ] . clear ( ( ) => { const error = chrome . runtime . lastError ; if ( error ) { reject ( error . message ) ; } else { resolve ( ) ; } } ) ; } else { this . backgroundStorageQuery < T > ( BrowserStorage . ON_CLEAR_MESSAGE , storageType ) . then ( ( ) => { resolve ( ) ; } ) ; } } ) ; } param storageType public usage ( storageType ) { this . verifyExtensionId ( ) ; return new Promise < AppStorageUsage > ( ( resolve , reject ) => { if ( this . hasStorageAccess ( ) ) { chrome . storage [ storageType ] . getBytesInUse ( ( bytesInUse ) => { const error = chrome . runtime . lastError ; if ( error ) { reject ( error . message ) ; } else { const storageUsage = { bytesInUse : bytesInUse , quotaBytes : chrome . storage [ storageType ] . QUOTA_BYTES , percentUsage : bytesInUse / chrome . storage [ storageType ] . QUOTA_BYTES * 100 , } ; resolve ( storageUsage ) ; } } ) ; } else { this . backgroundStorageQuery ( BrowserStorage . ON_USAGE_MESSAGE , storageType ) . then ( ( result ) => { resolve ( result ) ; } ) ; } } ) ; } /**
     * Check extension id exists
     */ private verifyExtensionId ( ) { if ( ! this . extensionId ) { throw new Error ( "Missing 'extensionId' property, please set it manually." ) ; } } /**
     *
     */ private hasStorageAccess ( ) { return ( chrome && chrome . storage !== undefined ) ; } param method param storageType param key param value private backgroundStorageQuery < T > ( method , storageType , key ? , value ? ) { return new Promise < T > ( ( resolve , reject ) => { const params = { storage : storageType , } ; if ( key !== undefined ) { params . key = key ; } if ( value !== undefined ) { params . value = value ; } chrome . runtime . sendMessage ( this . extensionId , { method : method , params : params } , ( result ) => { resolve ( result . data ) ; } ) ; } ) ; } }