import { Event , WrappedFunction } from '../types' ; import { isString } from './is' ; interface BeidouGlobal { __BEIDOU__ : { globalEventProcessors : any ; hub : any ; logger : any ; isInit : boolean ; } ; } param request export function dynamicRequire ( mod , request ) { return mod . require ( request ) ; } returns export function isNodeEnv ( ) { return Object . prototype . toString . call ( typeof process !== 'undefined' ? process : 0 ) === '[object process]' ; } const fallbackGlobalObject = { } ; returns export function getGlobalObject < T > ( ) { return ( isNodeEnv ( ) ? global : typeof window !== 'undefined' ? window : typeof self !== 'undefined' ? self : fallbackGlobalObject ) as T & typeof globalThis & BeidouGlobal ; } /**
 * Extended Window interface that allows for Crypto API usage in IE browsers
 */ interface MsCryptoWindow extends Window { msCrypto ? : Crypto ; } returns export function uuid4 ( ) { const global = getGlobalObject ( ) as MsCryptoWindow ; const crypto = global . crypto || global . msCrypto ; if ( ! ( crypto === void 0 ) && crypto . getRandomValues ) { const arr = new Uint16Array ( 8 ) ; crypto . getRandomValues ( arr ) ; arr [ 3 ] = ( arr [ 3 ] & 0xfff ) | 0x4000 ; arr [ 4 ] = ( arr [ 4 ] & 0x3fff ) | 0x8000 ; const pad = ( num ) : string => { let v = num . toString ( 16 ) ; while ( v . length < 4 ) { v = `0${ v }` ; } return v ; } ; return ( pad ( arr [ 0 ] ) + pad ( arr [ 1 ] ) + pad ( arr [ 2 ] ) + pad ( arr [ 3 ] ) + pad ( arr [ 4 ] ) + pad ( arr [ 5 ] ) + pad ( arr [ 6 ] ) + pad ( arr [ 7 ] ) ) ; } return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx' . replace ( /[xy]/g , c => { const r = ( Math . random ( ) * 16 ) | 0 ; const v = c === 'x' ? r : ( r & 0x3 ) | 0x8 ; return v . toString ( 16 ) ; } ) ; } returns export function parseUrl ( url ) { if ( ! url ) { return { } ; } const match = url . match ( /^(([^:/?#]+):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/ ) ; if ( ! match ) { return { } ; } const query = match [ 6 ] || '' ; const fragment = match [ 8 ] || '' ; return { host : match [ 4 ] , path : match [ 5 ] , protocol : match [ 2 ] , relative : match [ 5 ] + query + fragment , } ; } returns export function getEventDescription ( event ) { if ( event . message ) { return event . message ; } if ( event . exceptions && event . exceptions [ 0 ] ) { const exception = event . exceptions [ 0 ] ; if ( exception . content ) { return exception . content ; } } return '<unknown>' ; } /** JSDoc */ interface ExtensibleConsole extends Console { [ key ] : any ; } /** JSDoc */ export function consoleSandbox ( callback ) { const global = getGlobalObject < Window > ( ) ; const levels = [ 'debug' , 'info' , 'warn' , 'error' , 'log' , 'assert' ] ; if ( ! ( 'console' in global ) ) { return callback ( ) ; } const originalConsole = global . console as ExtensibleConsole ; const wrappedLevels = { } ; levels . forEach ( level => { if ( level in global . console && ( originalConsole [ level ] as WrappedFunction ) . __beidou_original__ ) { wrappedLevels [ level ] = originalConsole [ level ] as WrappedFunction ; originalConsole [ level ] = ( originalConsole [ level ] as WrappedFunction ) . __beidou_original__ ; } } ) ; const result = callback ( ) ; Object . keys ( wrappedLevels ) . forEach ( level => { originalConsole [ level ] = wrappedLevels [ level ] ; } ) ; return result ; } param event param value param type hidden export function addExceptionTypeValue ( event , value ? , type ? ) { event . exceptions = event . exceptions || [ ] ; event . exceptions [ 0 ] = event . exceptions [ 0 ] || { } ; event . exceptions [ 0 ] . content = event . exceptions [ 0 ] . content || `${ type }:${ value }` || '' ; } param event param mechanism hidden export function addExceptionMechanism ( event , mechanism = { } ) { try { event . exceptions ! [ 0 ] . mechanism = event . exceptions ! [ 0 ] . mechanism || { } ; Object . keys ( mechanism ) . forEach ( key => { event . exceptions ! [ 0 ] . mechanism [ key ] = mechanism [ key ] ; } ) ; } catch ( _oO ) { } } /**
 * A safe form of location.href
 */ export function getLocationHref ( ) { try { return document . location . href ; } catch ( oO ) { return '' ; } } /**
 * 判断是否是开发模式
 */ export function isDevHref ( ) { const _localHref = getLocationHref ( ) ; if ( _localHref . includes ( 'localhost' ) || _localHref . includes ( '127.0.0.1' ) ) { return true ; } return false ; } returns export function htmlTreeAsString ( elem ) { type SimpleNode = { parentNode : SimpleNode ; } | null ; try { let currentElem = elem as SimpleNode ; const MAX_TRAVERSE_HEIGHT = 5 ; const MAX_OUTPUT_LEN = 80 ; const out = [ ] ; let height = 0 ; let len = 0 ; const separator = ' > ' ; const sepLength = separator . length ; let nextStr ; while ( currentElem && height ++ < MAX_TRAVERSE_HEIGHT ) { nextStr = _htmlElementAsString ( currentElem ) ; if ( nextStr === 'html' || ( height > 1 && len + out . length * sepLength + nextStr . length >= MAX_OUTPUT_LEN ) ) { break ; } out . push ( nextStr ) ; len += nextStr . length ; currentElem = currentElem . parentNode ; } return out . reverse ( ) . join ( separator ) ; } catch ( _oO ) { return '<unknown>' ; } } returns function _htmlElementAsString ( el ) { const elem = el as { tagName ? : string ; id ? : string ; className ? : string ; getAttribute ( key ) : string ; } ; const out = [ ] ; let className ; let classes ; let key ; let attr ; let i ; if ( ! elem || ! elem . tagName ) { return '' ; } out . push ( elem . tagName . toLowerCase ( ) ) ; if ( elem . id ) { out . push ( `#${ elem . id }` ) ; } className = elem . className ; if ( className && isString ( className ) ) { classes = className . split ( /\s+/ ) ; for ( i = 0 ; i < classes . length ; i ++ ) { out . push ( `.${ classes [ i ] }` ) ; } } const allowedAttrs = [ 'type' , 'name' , 'title' , 'alt' ] ; for ( i = 0 ; i < allowedAttrs . length ; i ++ ) { key = allowedAttrs [ i ] ; attr = elem . getAttribute ( key ) ; if ( attr ) { out . push ( `[${ key }="${ attr }"]` ) ; } } return out . join ( '' ) ; } const INITIAL_TIME = Date . now ( ) ; let prevNow = 0 ; /**
 * Cross platform compatible partial performance implementation
 */ interface CrossPlatformPerformance { timeOrigin : number ; /**
     * Returns the current timestamp in ms
     */ now ( ) : number ; } const performanceFallback = { now ( ) { let now = Date . now ( ) - INITIAL_TIME ; if ( now < prevNow ) { now = prevNow ; } prevNow = now ; return now ; } , timeOrigin : INITIAL_TIME , } ; export const crossPlatformPerformance = ( ( ) : CrossPlatformPerformance => { if ( isNodeEnv ( ) ) { try { const perfHooks = dynamicRequire ( module , 'perf_hooks' ) as { performance : CrossPlatformPerformance ; } ; return perfHooks . performance ; } catch ( _ ) { return performanceFallback ; } } const { performance } = getGlobalObject < Window > ( ) ; if ( ! performance || ! performance . now ) { return performanceFallback ; } if ( performance . timeOrigin === undefined ) { performance . timeOrigin = ( performance . timing && performance . timing . navigationStart ) || INITIAL_TIME ; } return performance ; } ) ( ) ; /**
 * Returns a timestamp in seconds with milliseconds precision since the UNIX epoch calculated with the monotonic clock.
 */ export function timestampWithMs ( ) { return ( crossPlatformPerformance . timeOrigin + crossPlatformPerformance . now ( ) ) / 1000 ; } const SEMVER_REGEXP = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/ ; /**
 * Represents Semantic Versioning object
 */ interface SemVer { major ? : number ; minor ? : number ; patch ? : number ; prerelease ? : string ; buildmetadata ? : string ; } param input export function parseSemver ( input ) { const match = input . match ( SEMVER_REGEXP ) || [ ] ; const major = parseInt ( match [ 1 ] , 10 ) ; const minor = parseInt ( match [ 2 ] , 10 ) ; const patch = parseInt ( match [ 3 ] , 10 ) ; return { buildmetadata : match [ 5 ] , major : isNaN ( major ) ? undefined : major , minor : isNaN ( minor ) ? undefined : minor , patch : isNaN ( patch ) ? undefined : patch , prerelease : match [ 4 ] , } ; } const defaultRetryAfter = 60 * 1000 ; param now param header export function parseRetryAfterHeader ( now , header ? ) { if ( ! header ) { return defaultRetryAfter ; } const headerDelay = parseInt ( `${ header }` , 10 ) ; if ( ! isNaN ( headerDelay ) ) { return headerDelay * 1000 ; } const headerDate = Date . parse ( `${ header }` ) ; if ( ! isNaN ( headerDate ) ) { return headerDate - now ; } return defaultRetryAfter ; } const defaultFunctionName = '<anonymous>' ; /**
 * Safely extract function name from itself
 */ export function getFunctionName ( fn ) { try { if ( ! fn || typeof fn !== 'function' ) { return defaultFunctionName ; } return fn . name || defaultFunctionName ; } catch ( e ) { return defaultFunctionName ; } }