module import Analytics from './analytics' ; import Config from './config' ; import { DebuggingOptions , DebugOptions } from './debug' ; import DefaultMessenger , { Messenger } from './messenger' ; import DefaultPurchaseClient , { PurchaseClient } from './purchase-client' ; import SDK , { TriviaQuestionState , UserInfo } from './sdk' ; import StateClient from './state-client' ; import TwitchClient from './twitch-client' ; import Ext from './twitch-ext' ; import User from './user' ; import Util from './util' ; import * as PackageConfig from '../package.json' ; import { TwitchContext } from './twitch' ; export interface SDKMap { [ key ] : SDK ; } /**
 * Options that can be passed to Muxy.setup()
 *
 * `clientID` - The Extension Client ID as provided by Twitch.
 * `uaString` - An optional Google Analytics UA_String to send events to.
 * `quiet` - If true, will not print library information to the console. This is always
 *  true when running in production.
 */ export interface SetupOptions { clientID : string ; transactionsEnabled ? : boolean ; uaString ? : string ; quiet ? : boolean ; } ignore export interface DeprecatedSetupOptions { extensionID ? : string ; } export interface MuxyInterface { debug ( dbg ) : void ; setup ( options ) : void ; watchAuth ( extensionID ) : void ; TwitchClient ( ) : TwitchClient ; } /**
 * The main extension entry interface, available as the global `Muxy` object.
 *
 * This class handles environment detection, data harness collection and updates (for
 * authentication and backend communication) and SDK instance creation.
 *
 * On import or inclusion in an HTML file, a singleton object will be globally accessible
 * as `Muxy`.
 */ export class Muxy implements MuxyInterface { /**
     * Prints to console a description of the library's current version and
     * environment info. This is called automatically when the library is
     * setup, unless the `quiet` parameter is passed to  setup .
     *
     *  since public example public static printInfo ( ) { const SDKInfoText = [ 'Muxy Extensions SDK' , `v${ ( PackageConfig as any ) . version } © ${ new Date ( ) . getFullYear ( ) } ${ ( PackageConfig as any ) . author }` , ( PackageConfig as any ) . repository , '' ] ; const env = Util . currentEnvironment ( ) ; switch ( env ) { case Util . Environments . Production : SDKInfoText . push ( 'Running on production' ) ; break ; case Util . Environments . SandboxDev : SDKInfoText . push ( 'Running in sandbox environment outside of Twitch' ) ; break ; case Util . Environments . SandboxTwitch : SDKInfoText . push ( 'Running in sandbox environment on Twitch' ) ; break ; case Util . Environments . SandboxAdmin : SDKInfoText . push ( 'Running in sandbox environment in the Admin panel' ) ; break ; case Util . Environments . Admin : SDKInfoText . push ( 'Running in the Admin panel' ) ; break ; case Util . Environments . Testing : SDKInfoText . push ( 'Running in testing environment outside of Twitch' ) ; break ; case Util . Environments . Server : SDKInfoText . push ( 'Running on a NodeJS server' ) ; break ; default : SDKInfoText . push ( 'Could not determine execution environment.' ) ; if ( env ) { SDKInfoText . push ( `Current env string ${ env . environment }` ) ; } } Util . consolePrint ( SDKInfoText , { boxed : true } ) ; } since public param { string ? } id throws {Error} Will throw an error if called before  Muxy . setup .
     *
     *  returns { SDK } example public SDK = SDK ; /**
     * Makes trivia state enum available from the global `Muxy` object
     */ public TriviaQuestionState = TriviaQuestionState ; ignore public Util : Util ; public DebuggingOptions : typeof DebuggingOptions ; /**
     * Internal cache for created  SDK client objects mapped to SDK id.
     *
     *  ignore type { Object } public SDKClients : SDKMap ; /**
     * A flag used to signal when  setup has been called. This function must be called once
     * and only once before SDK objects may be created.
     *
     *  public type { boolean } public setupCalled : boolean ; public readonly type { string } public twitchClientID : string ; /**
     * Internal  StateClient .
     *
     *  ignore type { StateClient } public client : StateClient ; /**
     * Internal  Messenger .
     *
     *  ignore type { Messenger } public messenger : Messenger ; /**
     * Internal  PurchaseClient .
     *
     *  ignore type { PurchaseClient } public purchaseClient : PurchaseClient ; ignore type { boolean } public transactionsEnabled : boolean ; /**
     * Internal  TwitchClient .
     *
     *  ignore type { TwitchClient } public cachedTwitchClient : TwitchClient ; /**
     * Internal  Analytics .
     *
     *  ignore type { Analytics } public analytics : Analytics ; ignore type { TwitchContext } public context ? : TwitchContext ; /**
     * Internal reference to the current  User .
     *
     *  ignore type { User } public user : User ; ignore type { Promise } public loadPromise : Promise < void > ; public loadResolve : ( ) => void ; public loadReject : ( err : string ) => void ; public didLoad : boolean ; ignore type { Object } public SKUs : object [ ] ; ignore type { boolean } public watchingAuth : boolean ; /**
     * The Twitch Channel ID to use for testing. This will determine who the viewer and/or
     * broadcaster appears as when testing the extension.
     *
     * Changes to this value must be made before calling  SDK .
     *
     *  public type { string } public testChannelID : string ; /**
     * Role for the current user in the sandbox environment. May be one of  User . Roles .
     *
     * Changes to this value must be made before calling  SDK .
     *
     *  public type { string } public testJWTRole : string ; internal type { object } public debugOptions : DebugOptions ; ignore constructor ( ) { this . Util = Util ; this . setupCalled = false ; this . testChannelID = '23161357' ; this . testJWTRole = 'viewer' ; this . twitchClientID = '' ; this . SDKClients = { } ; this . client = null ; this . messenger = null ; this . cachedTwitchClient = null ; this . analytics = null ; this . user = null ; this . didLoad = false ; this . loadPromise = new Promise ( ( resolve , reject ) => { ignore this . loadResolve = resolve ; ignore this . loadReject = reject ; } ) ; this . SKUs = [ ] ; this . debugOptions = null ; this . watchingAuth = false ; StateClient . setEnvironment ( Util . currentEnvironment ( ) , null ) ; } /**
     * Called the first time the  setup is called to start watching the auth
     * and context callbacks and updating values automatically. This method should
     * not normally be called directly.
     *
     *  since ignore param { string } extensionID public watchAuth ( extensionID ) { const updateUserContextSettings = ( ) => { if ( ! this . user || ! this . context ) { return ; } if ( this . context . isFullScreen ) { this . user . videoMode = 'fullscreen' ; } else if ( this . context . isTheatreMode ) { this . user . videoMode = 'theatre' ; } else { this . user . videoMode = 'default' ; } this . user . game = this . context . game ; this . user . bitrate = Math . round ( this . context . bitrate || 0 ) ; this . user . latency = this . context . hlsLatencyBroadcaster ; this . user . buffer = this . context . bufferSize ; this . user . theme = this . context . theme ; this . user . volume = this . context . volume ; const keys = Object . keys ( this . SDKClients ) ; for ( const key of keys ) { this . SDKClients [ key ] . updateUser ( this . user ) ; } if ( this . context . bufferSize < 1 && this . analytics ) { this . analytics . user = this . user ; this . analytics . sendEvent ( 'video' , 'buffer' , 1 ) ; } } ; Ext . extensionID = extensionID ; Ext . onAuthorized ( this . debugOptions , ( auth ) => { if ( ! auth ) { this . loadReject ( 'Received invalid authorization from Twitch' ) ; return ; } this . twitchClientID = auth . clientId ; this . messenger . extensionID = auth . clientId ; this . messenger . channelID = auth . channelId ; this . client . updateAuth ( auth . token ) ; const resolvePromise = ( user ) => { this . user = user ; const keys = Object . keys ( this . SDKClients ) ; for ( const key of keys ) { this . SDKClients [ key ] . updateUser ( this . user ) ; } if ( this . analytics ) { this . analytics . user = this . user ; } } ; const onFirstAuth = ( ) => { this . client . immediateGetUserInfo ( extensionID ) . then ( ( userinfo ) => { const offset = userinfo . server_time - new Date ( ) . getTime ( ) ; const user = new User ( auth ) ; user . ip = userinfo . ip_address ; user . registeredWithMuxy = userinfo . registered || false ; user . visualizationID = userinfo . visualization_id || '' ; user . timeOffset = offset ; const keys = Object . keys ( this . SDKClients ) ; for ( const key of keys ) { this . SDKClients [ key ] . timeOffset = offset ; } updateUserContextSettings . call ( this ) ; this . didLoad = true ; resolvePromise ( user ) ; this . loadResolve ( ) ; } ) . catch ( ( err ) => { this . loadReject ( err ) ; } ) ; } ; if ( this . user ) { this . user . updateAuth ( auth ) ; resolvePromise ( this . user ) ; } else { onFirstAuth ( ) ; } } ) ; Ext . onContext ( ( context ) => { this . context = context ; if ( this . user ) { updateUserContextSettings . call ( this ) ; } const keys = Object . keys ( this . SDKClients ) ; for ( const key of keys ) { this . SDKClients [ key ] . contextObservers . notify ( context ) ; } } ) ; } since public param options param { string } options . clientID since param { string ? } options . uaString since param { boolean ? } options . quiet since throws example public setup ( options ) { if ( this . setupCalled ) { throw new Error ( 'Muxy.setup() can only be called once.' ) ; } if ( ! options ) { throw new Error ( 'Muxy.setup() was called with invalid options' ) ; } const clientID = options . clientID || options . extensionID ; if ( ! clientID ) { throw new Error ( 'Muxy.setup() was called without an Extension Client ID' ) ; } if ( ! this . debugOptions ) { const noop = ( ... args ) => { } ; this . debugOptions = { channelID : this . testChannelID , role : this . testJWTRole , onPubsubListen : noop , onPubsubReceive : noop , onPubsubSend : noop } ; } if ( this . debugOptions . environment ) { Util . overrideEnvironment = Util . Environments [ this . debugOptions . environment ] ; } this . client = new StateClient ( this . loadPromise , this . debugOptions ) ; this . messenger = DefaultMessenger ( this . debugOptions ) ; this . purchaseClient = DefaultPurchaseClient ( clientID ) ; this . transactionsEnabled = options . transactionsEnabled ; this . twitchClientID = clientID ; this . cachedTwitchClient = new TwitchClient ( this . twitchClientID ) ; this . cachedTwitchClient . promise = this . loadPromise ; if ( options . uaString ) { this . analytics = new Analytics ( options . uaString , this . loadPromise ) ; } if ( ! options . quiet ) { Muxy . printInfo ( ) ; } this . setupCalled = true ; } param { * } options public debug ( options ) { this . debugOptions = { channelID : this . testChannelID , role : this . testJWTRole , ... this . debugOptions , ... options . options } ; } since public returns { TwitchClient } throws {Error} Will throw an error if called before  Muxy . setup .
      public TwitchClient ( ) { return undefined ; } } Config . RegisterMoreEnvironments ( ) ; ignore const mxy = new Muxy ( ) ; ignore mxy . TwitchClient = function NewTwitchClient ( ) : TwitchClient { if ( ! mxy . setupCalled ) { throw new Error ( 'Muxy.setup() must be called before creating a new TwitchClient instance' ) ; } return mxy . cachedTwitchClient ; } ; mxy . DebuggingOptions = DebuggingOptions ; mxy [ 'default' ] = mxy ; ignore export default mxy ;