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