const COUNTER_STORE = "idCounter" ; let locked = false ; let currentCounter ; function sleep ( time ) { return new Promise ( resolve => setTimeout ( resolve , time ) ) ; } async function initializeCounter ( ) { currentCounter = JSON . parse ( ( await getItem ( COUNTER_STORE ) ) || "-1" ) ; } function getItem ( key ) { if ( navigator && navigator . product === "ReactNative" ) { const AsyncStorage = require ( "@react-native-community/async-storage" ) . default ; return AsyncStorage . getItem ( key ) ; } if ( window ) { const value = window . localStorage . getItem ( key ) ; return Promise . resolve ( value ) ; } return Promise . reject ( new Error ( "No storage API available" ) ) ; } function setItem ( key , value ) { if ( navigator && navigator . product === "ReactNative" ) { const AsyncStorage = require ( "@react-native-community/async-storage" ) . default ; return AsyncStorage . setItem ( key , value ) ; } if ( window ) { window . localStorage . setItem ( key , value ) ; return Promise . resolve ( ) ; } return Promise . reject ( new Error ( "No storage API available" ) ) ; } returns { Promise . < string > } export async function GenerateUniqueID ( ) { const sessionId = mx . session . getConfig ( "sessionObjectId" ) ; const rnd = Math . round ( Math . random ( ) * 10000 ) ; while ( locked ) { await sleep ( 10 ) ; } locked = true ; if ( typeof currentCounter === "undefined" ) { await initializeCounter ( ) ; } await setItem ( COUNTER_STORE , JSON . stringify ( ++ currentCounter ) ) ; locked = false ; return `${ sessionId }:${ currentCounter }:${ rnd }` ; }