{"version":3,"sources":["src/common.speech/Transcription/ConversationTranslatorRecognizer.ts"],"names":[],"mappings":"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","file":"ConversationTranslatorRecognizer.d.ts","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n// eslint-disable-next-line max-classes-per-file\nimport {\n    IAuthentication,\n    IConnectionFactory,\n    RecognizerConfig,\n    ServiceRecognizerBase,\n    SpeechServiceConfig\n} from \"../../common.speech/Exports.js\";\nimport {\n    BackgroundEvent,\n    Events,\n    Timeout,\n} from \"../../common/Exports.js\";\nimport { AudioConfigImpl } from \"../../sdk/Audio/AudioConfig.js\";\nimport { Contracts } from \"../../sdk/Contracts.js\";\nimport {\n    AudioConfig,\n    Connection,\n    ConnectionEventArgs,\n    ConversationExpirationEventArgs,\n    ConversationParticipantsChangedEventArgs,\n    ConversationTranslationCanceledEventArgs,\n    PropertyCollection,\n    PropertyId,\n    Recognizer,\n    SessionEventArgs,\n    SpeechTranslationConfig\n} from \"../../sdk/Exports.js\";\nimport { SpeechTranslationConfigImpl } from \"../../sdk/SpeechTranslationConfig.js\";\nimport { ConversationImpl } from \"../../sdk/Transcription/Conversation.js\";\nimport { Callback, IConversation } from \"../../sdk/Transcription/IConversation.js\";\nimport { ConversationConnectionFactory } from \"./ConversationConnectionFactory.js\";\nimport { ConversationServiceAdapter } from \"./ConversationServiceAdapter.js\";\nimport {\n    ConversationReceivedTranslationEventArgs,\n    LockRoomEventArgs,\n    MuteAllEventArgs,\n    ParticipantAttributeEventArgs,\n    ParticipantEventArgs,\n    ParticipantsListEventArgs\n} from \"./ConversationTranslatorEventArgs.js\";\nimport {\n    ConversationRecognizer,\n} from \"./ConversationTranslatorInterfaces.js\";\n\nexport class ConversationRecognizerFactory {\n    public static fromConfig(conversation: IConversation, speechConfig: SpeechTranslationConfig, audioConfig?: AudioConfig): ConversationRecognizer {\n        return new ConversationTranslatorRecognizer(conversation, speechConfig, audioConfig);\n    }\n}\n\n/**\n * Sends messages to the Conversation Translator websocket and listens for incoming events containing websocket messages.\n * Based off the recognizers in the SDK folder.\n */\nexport class ConversationTranslatorRecognizer extends Recognizer implements ConversationRecognizer {\n\n    private privIsDisposed: boolean;\n    private privSpeechRecognitionLanguage: string;\n    private privConnection: Connection;\n    private privConversation: ConversationImpl;\n    private privTimeoutToken: any;\n    private privSetTimeout: (cb: () => void, delay: number) => number;\n    private privClearTimeout: (id: number) => void;\n\n    public constructor(conversation: IConversation, speechConfig: SpeechTranslationConfig, audioConfig?: AudioConfig) {\n        const serviceConfigImpl = speechConfig as SpeechTranslationConfigImpl;\n        Contracts.throwIfNull(serviceConfigImpl, \"speechConfig\");\n        const conversationImpl = conversation as ConversationImpl;\n        Contracts.throwIfNull(conversationImpl, \"conversationImpl\");\n\n        super(audioConfig, serviceConfigImpl.properties, new ConversationConnectionFactory());\n\n        this.privConversation = conversationImpl;\n        this.privIsDisposed = false;\n        this.privProperties = serviceConfigImpl.properties.clone();\n        this.privConnection = Connection.fromRecognizer(this);\n        const webWorkerLoadType: string = this.privProperties.getProperty(PropertyId.WebWorkerLoadType, \"on\").toLowerCase();\n        if (webWorkerLoadType === \"on\" && typeof (Blob) !== \"undefined\" && typeof (Worker) !== \"undefined\") {\n            this.privSetTimeout = Timeout.setTimeout;\n            this.privClearTimeout = Timeout.clearTimeout;\n        } else {\n            if (typeof window !== \"undefined\") {\n                // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n                this.privSetTimeout = window.setTimeout.bind(window);\n                // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n                this.privClearTimeout = window.clearTimeout.bind(window);\n            } else {\n                this.privSetTimeout = setTimeout;\n                this.privClearTimeout = clearTimeout;\n            }\n        }\n    }\n\n    public canceled: (sender: ConversationRecognizer, event: ConversationTranslationCanceledEventArgs) => void;\n    public conversationExpiration: (sender: ConversationRecognizer, event: ConversationExpirationEventArgs) => void;\n    public lockRoomCommandReceived: (sender: ConversationRecognizer, event: LockRoomEventArgs) => void;\n    public muteAllCommandReceived: (sender: ConversationRecognizer, event: MuteAllEventArgs) => void;\n    public participantJoinCommandReceived: (sender: ConversationRecognizer, event: ParticipantEventArgs) => void;\n    public participantLeaveCommandReceived: (sender: ConversationRecognizer, event: ParticipantEventArgs) => void;\n    public participantUpdateCommandReceived: (sender: ConversationRecognizer, event: ParticipantAttributeEventArgs) => void;\n    public connectionOpened: (sender: ConversationRecognizer, event: SessionEventArgs) => void;\n    public connectionClosed: (sender: ConversationRecognizer, event: SessionEventArgs) => void;\n    public translationReceived: (sender: ConversationRecognizer, event: ConversationReceivedTranslationEventArgs) => void;\n    public participantsListReceived: (sender: ConversationRecognizer, event: ParticipantsListEventArgs) => void;\n    public participantsChanged: (sender: ConversationRecognizer, event: ConversationParticipantsChangedEventArgs) => void;\n\n    public set connected(cb: (e: ConnectionEventArgs) => void) {\n        this.privConnection.connected = cb;\n    }\n\n    public set disconnected(cb: (e: ConnectionEventArgs) => void) {\n        this.privConnection.disconnected = cb;\n    }\n\n    /**\n     * Return the speech language used by the recognizer\n     */\n    public get speechRecognitionLanguage(): string {\n        return this.privSpeechRecognitionLanguage;\n    }\n\n    /**\n     * Return the properties for the recognizer\n     */\n    public get properties(): PropertyCollection {\n        return this.privProperties;\n    }\n\n    public isDisposed(): boolean {\n        return this.privIsDisposed;\n    }\n\n    /**\n     * Connect to the recognizer\n     * @param token\n     */\n    public connect(token: string, cb?: () => void, err?: (e: string) => void): void {\n        try {\n            Contracts.throwIfDisposed(this.privIsDisposed);\n            Contracts.throwIfNullOrWhitespace(token, \"token\");\n            this.privReco.conversationTranslatorToken = token;\n            this.resetConversationTimeout();\n            this.privReco.connectAsync(cb, err);\n        } catch (error) {\n            if (!!err) {\n                if (error instanceof Error) {\n                    const typedError: Error = error;\n                    err(typedError.name + \": \" + typedError.message);\n                } else {\n                    err(error as string);\n                }\n            }\n        }\n    }\n\n    /**\n     * Disconnect from the recognizer\n     */\n    public disconnect(cb?: () => void, err?: (e: string) => void): void {\n        try {\n            Contracts.throwIfDisposed(this.privIsDisposed);\n            if (this.privTimeoutToken !== undefined) {\n               // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n               this.privClearTimeout(this.privTimeoutToken);\n            }\n            this.privReco.disconnect().then((): void => {\n                if (!!cb) {\n                    cb();\n                }\n            }, (error: string): void => {\n                if (!!err) {\n                    err(error);\n                }\n            });\n        } catch (error) {\n            if (!!err) {\n                if (error instanceof Error) {\n                    const typedError: Error = error;\n                    err(typedError.name + \": \" + typedError.message);\n                } else {\n                    err(error as string);\n                }\n            }\n            // Destroy the recognizer.\n            this.dispose(true).catch((reason: string): void => {\n                Events.instance.onEvent(new BackgroundEvent(reason));\n            });\n\n        }\n    }\n\n    /**\n     * Send the mute all participants command to the websocket\n     * @param conversationId\n     * @param participantId\n     * @param isMuted\n     */\n    public sendRequest(command: string, cb?: () => void, err?: (e: string) => void): void {\n        try {\n            Contracts.throwIfDisposed(this.privIsDisposed);\n            this.sendMessage(command, cb, err);\n        } catch (error) {\n            if (!!err) {\n                if (error instanceof Error) {\n                    const typedError: Error = error;\n                    err(typedError.name + \": \" + typedError.message);\n                } else {\n                    err(error as string);\n                }\n            }\n\n            // Destroy the recognizer.\n            this.dispose(true).catch((reason: string): void => {\n                Events.instance.onEvent(new BackgroundEvent(reason));\n            });\n\n        }\n    }\n\n    /**\n     * Handle update of service auth token (#694)\n     */\n    public onToken(token: IAuthentication): void {\n        this.privConversation.onToken(token);\n    }\n\n    /**\n     * Close and dispose the recognizer\n     */\n    public async close(): Promise<void> {\n        if (!this.privIsDisposed) {\n            if (!!this.privConnection) {\n                this.privConnection.closeConnection();\n                this.privConnection.close();\n            }\n            this.privConnection = undefined;\n            await this.dispose(true);\n        }\n    }\n\n    /**\n     * Dispose the recognizer\n     * @param disposing\n     */\n    protected async dispose(disposing: boolean): Promise<void> {\n        if (this.privIsDisposed) {\n            return;\n        }\n        if (disposing) {\n            if (this.privTimeoutToken !== undefined) {\n                // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n                this.privClearTimeout(this.privTimeoutToken);\n            }\n            this.privIsDisposed = true;\n            if (!!this.privConnection) {\n                this.privConnection.closeConnection();\n                this.privConnection.close();\n                this.privConnection = undefined;\n            }\n            await super.dispose(disposing);\n        }\n    }\n\n    /**\n     * Create the config for the recognizer\n     * @param speechConfig\n     */\n    protected createRecognizerConfig(speechConfig: SpeechServiceConfig): RecognizerConfig {\n        return new RecognizerConfig(speechConfig, this.privProperties);\n    }\n\n    /**\n     * Create the service recognizer.\n     * The audio source is redundnant here but is required by the implementation.\n     * @param authentication\n     * @param connectionFactory\n     * @param audioConfig\n     * @param recognizerConfig\n     */\n    protected createServiceRecognizer(\n        authentication: IAuthentication,\n        connectionFactory: IConnectionFactory,\n        audioConfig: AudioConfig,\n        recognizerConfig: RecognizerConfig): ServiceRecognizerBase {\n\n        const audioSource: AudioConfigImpl = audioConfig as AudioConfigImpl;\n\n        return new ConversationServiceAdapter(authentication, connectionFactory, audioSource, recognizerConfig, this);\n    }\n\n    private sendMessage(msg: string, cb?: Callback, err?: Callback): void {\n        const withAsync = this.privReco as ConversationServiceAdapter;\n        const PromiseToEmptyCallback = <T>(promise: Promise<T>, cb?: Callback, err?: Callback): void => {\n            if (promise !== undefined) {\n                promise.then((): void => {\n                    try {\n                        if (!!cb) {\n                            cb();\n                        }\n                    } catch (e) {\n                        if (!!err) {\n                            err(`'Unhandled error on promise callback: ${e as string}'`);\n                        }\n                    }\n                }, (reason: any): void => {\n                    try {\n                        if (!!err) {\n                            err(reason);\n                        }\n                        // eslint-disable-next-line no-empty\n                    } catch (error) { }\n                });\n            } else {\n                if (!!err) {\n                    err(\"Null promise\");\n                }\n            }\n        };\n\n        PromiseToEmptyCallback(withAsync.sendMessageAsync(msg), cb, err);\n        this.resetConversationTimeout();\n    }\n\n    private resetConversationTimeout(): void {\n        if (this.privTimeoutToken !== undefined) {\n            // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n            this.privClearTimeout(this.privTimeoutToken);\n        }\n\n        this.privTimeoutToken = this.privSetTimeout((): void => {\n            this.sendRequest(this.privConversation.getKeepAlive());\n        }, 60000);\n    }\n\n}\n"]}