import { Child , Parent } from "pym.js" ; import { v1 as uuid } from "uuid" ; import { globalErrorReporter } from "../errors" ; import { PromisifiedStorage } from "./PromisifiedStorage" ; type Pym = Child | Parent ; interface Request { resolve : ( v : any ) => void ; reject : ( v : any ) => void ; } class PymStorage implements PromisifiedStorage { /** Instance to pym */ private pym : Pym ; /** Requested storage type */ private type : string ; /** A Map of requestID => Request */ private requests : Record < string , Request > = { } ; /** Requests method with parameters over pym. */ private call < T > ( method , parameters = { } ) { const id = uuid ( ) ; return new Promise ( ( resolve , reject ) => { this . requests [ id ] = { resolve , reject } ; if ( process . env . NODE_ENV !== "production" ) { console . debug ( `pymStorage.${ this . type }.request` , { id , method , parameters , } ) ; } this . pym . sendMessage ( `pymStorage.${ this . type }.request` , JSON . stringify ( { id , method , parameters , } ) ) ; } ) ; } /** Listen to pym responses */ private listen ( ) { this . pym . onMessage ( `pymStorage.${ this . type }.response` , ( msg ) => { const { id , result } = JSON . parse ( msg ) ; if ( process . env . NODE_ENV !== "production" ) { console . debug ( `pymStorage.${ this . type }.response` , { id , result } ) ; } if ( id in this . requests ) { this . requests [ id ] . resolve ( result ) ; delete this . requests [ id ] ; } else { globalErrorReporter . report ( `pymStorage.${ this . type }.response for missing request: ${ id }` ) ; } } ) ; this . pym . onMessage ( `pymStorage.${ this . type }.error` , ( msg ) => { const { id , error } = JSON . parse ( msg ) ; if ( process . env . NODE_ENV !== "production" ) { console . debug ( `pymStorage.${ this . type }.error` , { id , error } ) ; } if ( id in this . requests ) { this . requests [ id ] . reject ( new Error ( error ) ) ; delete this . requests [ id ] ; } else { globalErrorReporter . report ( `pymStorage.${ this . type }.error for missing request: ${ id }` ) ; } } ) ; } constructor ( pym , type ) { this . pym = pym ; this . type = type ; this . listen ( ) ; } public get length ( ) { return this . call < number > ( "length" ) ; } public key ( n ) { return this . call < string | null > ( "key" , { n } ) ; } public clear ( ) { return this . call < void > ( "clear" ) ; } public setItem ( key , value ) { return this . call < void > ( "setItem" , { key , value } ) ; } public getItem ( key ) { return this . call < string | null > ( "getItem" , { key } ) ; } public removeItem ( key ) { return this . call < void > ( "removeItem" , { key } ) ; } } param { string } pym returns { object } export default function createPymStorage ( pym , type ) { return new PymStorage ( pym , type ) ; }