botframework-webchat 4.13.0 → 4.14.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintignore +1 -9
- package/.eslintrc.yml +5 -0
- package/README.md +33 -36
- package/babel.config.json +2 -2
- package/babel.sanitize-html.config.json +10 -0
- package/lib/AddFullBundle.d.ts +30 -0
- package/lib/AddFullBundle.d.ts.map +1 -0
- package/lib/AddFullBundle.js +77 -0
- package/lib/FullComposer.d.ts +8 -0
- package/lib/FullComposer.d.ts.map +1 -0
- package/lib/FullComposer.js +6 -16
- package/lib/FullReactWebChat.d.ts +8 -0
- package/lib/FullReactWebChat.d.ts.map +1 -0
- package/lib/FullReactWebChat.js +8 -23
- package/lib/adaptiveCards/AdaptiveCardsComposer.d.ts +10 -0
- package/lib/adaptiveCards/AdaptiveCardsComposer.d.ts.map +1 -0
- package/lib/adaptiveCards/AdaptiveCardsComposer.js +6 -2
- package/lib/adaptiveCards/AdaptiveCardsContext.d.ts +8 -0
- package/lib/adaptiveCards/AdaptiveCardsContext.d.ts.map +1 -0
- package/lib/adaptiveCards/AdaptiveCardsContext.js +3 -3
- package/lib/adaptiveCards/AdaptiveCardsStyleOptions.d.ts +5 -3
- package/lib/adaptiveCards/AdaptiveCardsStyleOptions.d.ts.map +1 -1
- package/lib/adaptiveCards/AdaptiveCardsStyleSet.d.ts +7 -0
- package/lib/adaptiveCards/AdaptiveCardsStyleSet.d.ts.map +1 -0
- package/lib/{FullBundleStyleOptions.js → adaptiveCards/AdaptiveCardsStyleSet.js} +0 -0
- package/lib/adaptiveCards/Attachment/AdaptiveCardAttachment.d.ts +9 -0
- package/lib/adaptiveCards/Attachment/AdaptiveCardAttachment.d.ts.map +1 -0
- package/lib/adaptiveCards/Attachment/AdaptiveCardAttachment.js +1 -1
- package/lib/adaptiveCards/Attachment/AdaptiveCardBuilder.d.ts +28 -0
- package/lib/adaptiveCards/Attachment/AdaptiveCardBuilder.d.ts.map +1 -0
- package/lib/adaptiveCards/Attachment/AdaptiveCardBuilder.js +4 -4
- package/lib/adaptiveCards/Attachment/AdaptiveCardContent.d.ts +9 -0
- package/lib/adaptiveCards/Attachment/AdaptiveCardContent.d.ts.map +1 -0
- package/lib/adaptiveCards/Attachment/AdaptiveCardContent.js +8 -4
- package/lib/adaptiveCards/Attachment/AdaptiveCardRenderer.d.ts +11 -0
- package/lib/adaptiveCards/Attachment/AdaptiveCardRenderer.d.ts.map +1 -0
- package/lib/adaptiveCards/Attachment/AdaptiveCardRenderer.js +210 -49
- package/lib/adaptiveCards/Attachment/AnimationCardContent.d.ts +10 -0
- package/lib/adaptiveCards/Attachment/AnimationCardContent.d.ts.map +1 -0
- package/lib/adaptiveCards/Attachment/AnimationCardContent.js +1 -1
- package/lib/adaptiveCards/Attachment/AudioCardContent.d.ts +10 -0
- package/lib/adaptiveCards/Attachment/AudioCardContent.d.ts.map +1 -0
- package/lib/adaptiveCards/Attachment/AudioCardContent.js +1 -1
- package/lib/adaptiveCards/Attachment/CommonCard.js +11 -6
- package/lib/adaptiveCards/Attachment/HeroCardContent.d.ts +10 -0
- package/lib/adaptiveCards/Attachment/HeroCardContent.d.ts.map +1 -0
- package/lib/adaptiveCards/Attachment/HeroCardContent.js +11 -6
- package/lib/adaptiveCards/Attachment/OAuthCardContent.d.ts +10 -0
- package/lib/adaptiveCards/Attachment/OAuthCardContent.d.ts.map +1 -0
- package/lib/adaptiveCards/Attachment/OAuthCardContent.js +11 -6
- package/lib/adaptiveCards/Attachment/ReceiptCardContent.d.ts +10 -0
- package/lib/adaptiveCards/Attachment/ReceiptCardContent.d.ts.map +1 -0
- package/lib/adaptiveCards/Attachment/ReceiptCardContent.js +11 -6
- package/lib/adaptiveCards/Attachment/SignInCardContent.d.ts +10 -0
- package/lib/adaptiveCards/Attachment/SignInCardContent.d.ts.map +1 -0
- package/lib/adaptiveCards/Attachment/SignInCardContent.js +1 -1
- package/lib/adaptiveCards/Attachment/ThumbnailCardContent.d.ts +10 -0
- package/lib/adaptiveCards/Attachment/ThumbnailCardContent.d.ts.map +1 -0
- package/lib/adaptiveCards/Attachment/ThumbnailCardContent.js +11 -6
- package/lib/adaptiveCards/Attachment/VideoCardContent.d.ts +20 -0
- package/lib/adaptiveCards/Attachment/VideoCardContent.d.ts.map +1 -0
- package/lib/adaptiveCards/Attachment/VideoCardContent.js +7 -5
- package/lib/adaptiveCards/AttachmentForScreenReader/AdaptiveCardAttachment.js +7 -3
- package/lib/adaptiveCards/AttachmentForScreenReader/RichCardAttachment.js +1 -1
- package/lib/adaptiveCards/Styles/StyleSet/AdaptiveCardRenderer.d.ts +56 -0
- package/lib/adaptiveCards/Styles/StyleSet/AdaptiveCardRenderer.d.ts.map +1 -0
- package/lib/adaptiveCards/Styles/StyleSet/AdaptiveCardRenderer.js +1 -1
- package/lib/adaptiveCards/Styles/adaptiveCardHostConfig.d.ts +126 -0
- package/lib/adaptiveCards/Styles/adaptiveCardHostConfig.d.ts.map +1 -0
- package/lib/adaptiveCards/Styles/adaptiveCardHostConfig.js +29 -9
- package/lib/adaptiveCards/Styles/createAdaptiveCardsStyleSet.d.ts +5 -0
- package/lib/adaptiveCards/Styles/createAdaptiveCardsStyleSet.d.ts.map +1 -0
- package/lib/adaptiveCards/Styles/createAdaptiveCardsStyleSet.js +2 -2
- package/lib/adaptiveCards/createAdaptiveCardsAttachmentForScreenReaderMiddleware.d.ts +3 -0
- package/lib/adaptiveCards/createAdaptiveCardsAttachmentForScreenReaderMiddleware.d.ts.map +1 -0
- package/lib/adaptiveCards/createAdaptiveCardsAttachmentForScreenReaderMiddleware.js +5 -11
- package/lib/adaptiveCards/createAdaptiveCardsAttachmentMiddleware.d.ts +3 -0
- package/lib/adaptiveCards/createAdaptiveCardsAttachmentMiddleware.d.ts.map +1 -0
- package/lib/adaptiveCards/createAdaptiveCardsAttachmentMiddleware.js +29 -39
- package/lib/adaptiveCards/defaultStyleOptions.d.ts +4 -0
- package/lib/adaptiveCards/defaultStyleOptions.d.ts.map +1 -0
- package/lib/adaptiveCards/defaultStyleOptions.js +3 -2
- package/lib/adaptiveCards/hooks/internal/useAdaptiveCardsContext.d.ts +3 -0
- package/lib/adaptiveCards/hooks/internal/useAdaptiveCardsContext.d.ts.map +1 -0
- package/lib/adaptiveCards/hooks/internal/useAdaptiveCardsContext.js +1 -1
- package/lib/adaptiveCards/hooks/internal/useParseAdaptiveCardJSON.d.ts +2 -0
- package/lib/adaptiveCards/hooks/internal/useParseAdaptiveCardJSON.d.ts.map +1 -0
- package/lib/adaptiveCards/hooks/internal/useParseAdaptiveCardJSON.js +7 -5
- package/lib/adaptiveCards/hooks/internal/useUniqueId.js +1 -1
- package/lib/adaptiveCards/hooks/useAdaptiveCardsHostConfig.d.ts +2 -0
- package/lib/adaptiveCards/hooks/useAdaptiveCardsHostConfig.d.ts.map +1 -0
- package/lib/adaptiveCards/hooks/useAdaptiveCardsHostConfig.js +3 -5
- package/lib/adaptiveCards/hooks/useAdaptiveCardsPackage.d.ts +3 -0
- package/lib/adaptiveCards/hooks/useAdaptiveCardsPackage.d.ts.map +1 -0
- package/lib/adaptiveCards/hooks/useAdaptiveCardsPackage.js +1 -1
- package/lib/adaptiveCards/normalizeStyleOptions.d.ts +3 -0
- package/lib/adaptiveCards/normalizeStyleOptions.d.ts.map +1 -0
- package/lib/adaptiveCards/normalizeStyleOptions.js +1 -1
- package/lib/addVersion.js +2 -2
- package/lib/createBrowserWebSpeechPonyfillFactory.d.ts +3 -0
- package/lib/createBrowserWebSpeechPonyfillFactory.d.ts.map +1 -0
- package/lib/createBrowserWebSpeechPonyfillFactory.js +7 -4
- package/lib/createCognitiveServicesSpeechServicesPonyfillFactory.d.ts +17 -0
- package/lib/createCognitiveServicesSpeechServicesPonyfillFactory.d.ts.map +1 -0
- package/lib/createCognitiveServicesSpeechServicesPonyfillFactory.js +17 -11
- package/lib/createDirectLine.d.ts +17 -0
- package/lib/createDirectLine.d.ts.map +1 -0
- package/lib/createDirectLine.js +3 -2
- package/lib/createDirectLineAppServiceExtension.d.ts +7 -0
- package/lib/createDirectLineAppServiceExtension.d.ts.map +1 -0
- package/lib/createDirectLineAppServiceExtension.js +1 -1
- package/lib/createDirectLineSpeechAdapters.d.ts +25 -0
- package/lib/createDirectLineSpeechAdapters.d.ts.map +1 -0
- package/lib/createDirectLineSpeechAdapters.js +57 -3
- package/lib/createFullStyleSet.d.ts +1106 -0
- package/lib/createFullStyleSet.d.ts.map +1 -0
- package/lib/createFullStyleSet.js +2 -2
- package/lib/fullBundleDefaultStyleOptions.js +4 -4
- package/lib/hooks/useStyleOptions.d.ts +3 -0
- package/lib/hooks/useStyleOptions.d.ts.map +1 -0
- package/lib/hooks/useStyleOptions.js +21 -0
- package/lib/index-es5.d.ts +24 -20
- package/lib/index-es5.d.ts.map +1 -1
- package/lib/index-es5.js +2 -2
- package/lib/index-minimal.d.ts +9 -6
- package/lib/index-minimal.d.ts.map +1 -1
- package/lib/index-minimal.js +8 -4
- package/lib/index.d.ts +154 -18
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +11 -7
- package/lib/renderMarkdown.d.ts +6 -0
- package/lib/renderMarkdown.d.ts.map +1 -0
- package/lib/renderMarkdown.js +5 -2
- package/lib/renderWebChat.d.ts +3 -0
- package/lib/renderWebChat.d.ts.map +1 -0
- package/lib/renderWebChat.js +1 -1
- package/lib/speech/CustomAudioInputStream.d.ts +94 -0
- package/lib/speech/CustomAudioInputStream.d.ts.map +1 -0
- package/lib/speech/CustomAudioInputStream.js +416 -0
- package/lib/speech/bytesPerSample.d.ts +2 -0
- package/lib/speech/bytesPerSample.d.ts.map +1 -0
- package/lib/speech/bytesPerSample.js +12 -0
- package/lib/speech/createAudioConfig.d.ts +23 -0
- package/lib/speech/createAudioConfig.d.ts.map +1 -0
- package/lib/speech/createAudioConfig.js +84 -0
- package/lib/speech/createAudioContext.d.ts +3 -0
- package/lib/speech/createAudioContext.d.ts.map +1 -0
- package/lib/speech/createAudioContext.js +22 -0
- package/lib/speech/createMicrophoneAudioConfigAndAudioContext.d.ts +9 -0
- package/lib/speech/createMicrophoneAudioConfigAndAudioContext.d.ts.map +1 -0
- package/lib/speech/createMicrophoneAudioConfigAndAudioContext.js +161 -0
- package/lib/speech/getUserMedia.d.ts +2 -0
- package/lib/speech/getUserMedia.d.ts.map +1 -0
- package/lib/speech/getUserMedia.js +25 -0
- package/lib/types/AdaptiveCardsPackage.d.ts +13 -0
- package/lib/types/AdaptiveCardsPackage.d.ts.map +1 -0
- package/lib/types/AdaptiveCardsPackage.js +2 -0
- package/lib/types/CognitiveServicesAudioOutputFormat.d.ts +3 -0
- package/lib/types/CognitiveServicesAudioOutputFormat.d.ts.map +1 -0
- package/lib/types/CognitiveServicesAudioOutputFormat.js +2 -0
- package/lib/types/CognitiveServicesCredentials.d.ts +18 -0
- package/lib/types/CognitiveServicesCredentials.d.ts.map +1 -0
- package/lib/types/CognitiveServicesCredentials.js +2 -0
- package/lib/types/CognitiveServicesTextNormalization.d.ts +3 -0
- package/lib/types/CognitiveServicesTextNormalization.d.ts.map +1 -0
- package/lib/types/CognitiveServicesTextNormalization.js +2 -0
- package/lib/{FullBundleStyleOptions.d.ts → types/FullBundleStyleOptions.d.ts} +1 -1
- package/lib/types/FullBundleStyleOptions.d.ts.map +1 -0
- package/lib/types/FullBundleStyleOptions.js +2 -0
- package/lib/useComposerProps.d.ts +22 -0
- package/lib/useComposerProps.d.ts.map +1 -0
- package/lib/useComposerProps.js +6 -8
- package/package.json +51 -46
- package/src/AddFullBundle.tsx +94 -0
- package/src/FullComposer.tsx +38 -0
- package/src/FullReactWebChat.tsx +32 -0
- package/src/__tests__/createDirectLine.spec.js +2 -0
- package/src/__tests__/renderMarkdown.spec.js +1 -1
- package/src/__tests__/versionTag.es5.spec.js +3 -0
- package/src/__tests__/versionTag.full.spec.js +3 -0
- package/src/__tests__/versionTag.minimal.spec.js +3 -0
- package/src/adaptiveCards/{AdaptiveCardsComposer.js → AdaptiveCardsComposer.tsx} +17 -5
- package/src/adaptiveCards/AdaptiveCardsContext.ts +12 -0
- package/src/adaptiveCards/AdaptiveCardsStyleOptions.ts +5 -3
- package/src/adaptiveCards/AdaptiveCardsStyleSet.ts +7 -0
- package/src/adaptiveCards/Attachment/{AdaptiveCardAttachment.js → AdaptiveCardAttachment.tsx} +8 -2
- package/src/adaptiveCards/Attachment/AdaptiveCardBuilder.ts +21 -15
- package/src/adaptiveCards/Attachment/{AdaptiveCardContent.js → AdaptiveCardContent.tsx} +8 -2
- package/src/adaptiveCards/Attachment/{AdaptiveCardRenderer.js → AdaptiveCardRenderer.tsx} +228 -46
- package/src/adaptiveCards/Attachment/{AnimationCardContent.js → AnimationCardContent.tsx} +9 -2
- package/src/adaptiveCards/Attachment/{AudioCardContent.js → AudioCardContent.tsx} +9 -2
- package/src/adaptiveCards/Attachment/CommonCard.js +2 -1
- package/src/adaptiveCards/Attachment/{HeroCardContent.js → HeroCardContent.tsx} +12 -3
- package/src/adaptiveCards/Attachment/{OAuthCardContent.js → OAuthCardContent.tsx} +11 -3
- package/src/adaptiveCards/Attachment/{ReceiptCardContent.js → ReceiptCardContent.tsx} +58 -28
- package/src/adaptiveCards/Attachment/{SignInCardContent.js → SignInCardContent.tsx} +9 -2
- package/src/adaptiveCards/Attachment/{ThumbnailCardContent.js → ThumbnailCardContent.tsx} +12 -3
- package/src/adaptiveCards/Attachment/{VideoCardContent.js → VideoCardContent.tsx} +15 -3
- package/src/adaptiveCards/Styles/StyleSet/AdaptiveCardRenderer.ts +1 -1
- package/src/adaptiveCards/Styles/adaptiveCardHostConfig.ts +28 -8
- package/src/adaptiveCards/Styles/createAdaptiveCardsStyleSet.spec.js +2 -0
- package/src/adaptiveCards/Styles/createAdaptiveCardsStyleSet.ts +7 -4
- package/src/adaptiveCards/{createAdaptiveCardsAttachmentForScreenReaderMiddleware.js → createAdaptiveCardsAttachmentForScreenReaderMiddleware.tsx} +16 -15
- package/src/adaptiveCards/createAdaptiveCardsAttachmentMiddleware.tsx +45 -0
- package/src/adaptiveCards/defaultStyleOptions.ts +2 -1
- package/src/adaptiveCards/hooks/internal/{useAdaptiveCardsContext.js → useAdaptiveCardsContext.ts} +1 -1
- package/src/adaptiveCards/hooks/internal/{useParseAdaptiveCardJSON.js → useParseAdaptiveCardJSON.ts} +5 -2
- package/src/adaptiveCards/hooks/internal/{useUniqueId.js → useUniqueId.ts} +1 -1
- package/src/adaptiveCards/hooks/{useAdaptiveCardsHostConfig.js → useAdaptiveCardsHostConfig.ts} +6 -8
- package/src/adaptiveCards/hooks/{useAdaptiveCardsPackage.js → useAdaptiveCardsPackage.ts} +2 -1
- package/src/createBrowserWebSpeechPonyfillFactory.ts +21 -0
- package/src/createCognitiveServicesSpeechServicesPonyfillFactory.spec.js +37 -6
- package/src/createCognitiveServicesSpeechServicesPonyfillFactory.ts +78 -0
- package/src/createDirectLine.ts +65 -0
- package/src/createDirectLineAppServiceExtension.ts +22 -0
- package/src/createDirectLineSpeechAdapters.ts +84 -0
- package/src/createFullStyleSet.ts +2 -2
- package/src/fullBundleDefaultStyleOptions.ts +3 -3
- package/src/hooks/useStyleOptions.ts +9 -0
- package/src/index-es5.ts +0 -2
- package/src/index-minimal.ts +3 -2
- package/src/index.ts +22 -10
- package/src/{renderMarkdown.js → renderMarkdown.ts} +8 -1
- package/src/renderWebChat.tsx +6 -0
- package/src/speech/CustomAudioInputStream.ts +325 -0
- package/src/speech/bytesPerSample.ts +4 -0
- package/src/speech/createAudioConfig.spec.js +23 -0
- package/src/speech/createAudioConfig.ts +70 -0
- package/src/speech/createAudioContext.ts +16 -0
- package/src/speech/createMicrophoneAudioConfigAndAudioContext.ts +146 -0
- package/src/speech/getUserMedia.ts +14 -0
- package/src/tsconfig.json +1 -1
- package/src/types/AdaptiveCardsPackage.ts +23 -0
- package/src/types/CognitiveServicesAudioOutputFormat.ts +28 -0
- package/src/types/CognitiveServicesCredentials.ts +28 -0
- package/src/types/CognitiveServicesTextNormalization.ts +3 -0
- package/src/{FullBundleStyleOptions.ts → types/FullBundleStyleOptions.ts} +1 -1
- package/src/{useComposerProps.js → useComposerProps.ts} +21 -11
- package/webpack.config.js +46 -6
- package/lib/FullBundleStyleOptions.d.ts.map +0 -1
- package/src/FullComposer.js +0 -40
- package/src/FullReactWebChat.js +0 -47
- package/src/adaptiveCards/AdaptiveCardsContext.js +0 -5
- package/src/adaptiveCards/createAdaptiveCardsAttachmentMiddleware.js +0 -41
- package/src/createBrowserWebSpeechPonyfillFactory.js +0 -16
- package/src/createCognitiveServicesSpeechServicesPonyfillFactory.js +0 -58
- package/src/createDirectLine.js +0 -38
- package/src/createDirectLineAppServiceExtension.js +0 -12
- package/src/createDirectLineSpeechAdapters.js +0 -5
- package/src/index-es5.tsx +0 -49
- package/src/index-minimal.tsx +0 -9
- package/src/index.tsx +0 -45
- package/src/renderWebChat.js +0 -6
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { AudioConfig } from 'microsoft-cognitiveservices-speech-sdk';
|
|
2
|
+
import { createAdapters } from 'botframework-directlinespeech-sdk';
|
|
3
|
+
import { DirectLineJSBotConnection } from 'botframework-webchat-core';
|
|
4
|
+
import { WebSpeechPonyfill } from 'botframework-webchat-api';
|
|
5
|
+
|
|
6
|
+
import CognitiveServicesAudioOutputFormat from './types/CognitiveServicesAudioOutputFormat';
|
|
7
|
+
import CognitiveServicesCredentials from './types/CognitiveServicesCredentials';
|
|
8
|
+
import CognitiveServicesTextNormalization from './types/CognitiveServicesTextNormalization';
|
|
9
|
+
import createMicrophoneAudioConfigAndAudioContext from './speech/createMicrophoneAudioConfigAndAudioContext';
|
|
10
|
+
|
|
11
|
+
const DEFAULT_LANGUAGE = 'en-US';
|
|
12
|
+
|
|
13
|
+
// TODO: When using DLSpeech via bundle, we will add our own MicrophoneAudioConfig.
|
|
14
|
+
export default function createDirectLineSpeechAdapters({
|
|
15
|
+
audioConfig,
|
|
16
|
+
audioContext,
|
|
17
|
+
audioInputDeviceId,
|
|
18
|
+
enableInternalHTTPSupport,
|
|
19
|
+
enableTelemetry,
|
|
20
|
+
fetchCredentials,
|
|
21
|
+
speechRecognitionEndpointId,
|
|
22
|
+
speechRecognitionLanguage = window?.navigator?.language || DEFAULT_LANGUAGE,
|
|
23
|
+
speechSynthesisDeploymentId,
|
|
24
|
+
speechSynthesisOutputFormat,
|
|
25
|
+
textNormalization,
|
|
26
|
+
userID,
|
|
27
|
+
username
|
|
28
|
+
}: {
|
|
29
|
+
audioConfig?: AudioConfig;
|
|
30
|
+
audioContext?: AudioContext;
|
|
31
|
+
audioInputDeviceId?: string;
|
|
32
|
+
enableInternalHTTPSupport?: true;
|
|
33
|
+
enableTelemetry?: true;
|
|
34
|
+
fetchCredentials: CognitiveServicesCredentials;
|
|
35
|
+
speechRecognitionEndpointId?: string;
|
|
36
|
+
speechRecognitionLanguage?: string;
|
|
37
|
+
speechSynthesisDeploymentId?: string;
|
|
38
|
+
speechSynthesisOutputFormat?: CognitiveServicesAudioOutputFormat;
|
|
39
|
+
textNormalization?: CognitiveServicesTextNormalization;
|
|
40
|
+
userID?: string;
|
|
41
|
+
username?: string;
|
|
42
|
+
}): {
|
|
43
|
+
directLine: DirectLineJSBotConnection;
|
|
44
|
+
webSpeechPonyfill: WebSpeechPonyfill;
|
|
45
|
+
} {
|
|
46
|
+
if (audioConfig) {
|
|
47
|
+
audioInputDeviceId &&
|
|
48
|
+
console.warn(
|
|
49
|
+
'botframework-webchat: "audioConfig" and "audioInputDeviceId" cannot be set at the same time; ignoring "audioInputDeviceId".'
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
audioContext &&
|
|
53
|
+
console.warn(
|
|
54
|
+
'botframework-webchat: "audioConfig" and "audioContext" cannot be set at the same time; ignoring "audioContext" for speech recognition.'
|
|
55
|
+
);
|
|
56
|
+
} else if (!window.navigator.mediaDevices) {
|
|
57
|
+
// If the browser does not support or allow microphone access, we will continue to create Direct Line Speech adapter without custom "audioConfig" and "audioContext".
|
|
58
|
+
// In Direct Line Speech SDK, it will disable speech functionality, only leaving text chat available via the protocol.
|
|
59
|
+
console.warn(
|
|
60
|
+
'botframework-webchat: Your browser does not support or allow microphone access or the page is not loaded via HTTPS or localhost. Speech is disabled for Direct Line Speech. However, you may pass a custom "audioConfig" to enable speech in this environment.'
|
|
61
|
+
);
|
|
62
|
+
} else {
|
|
63
|
+
({ audioConfig, audioContext } = createMicrophoneAudioConfigAndAudioContext({
|
|
64
|
+
audioContext,
|
|
65
|
+
audioInputDeviceId,
|
|
66
|
+
enableTelemetry
|
|
67
|
+
}));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return createAdapters({
|
|
71
|
+
audioConfig,
|
|
72
|
+
audioContext,
|
|
73
|
+
enableInternalHTTPSupport,
|
|
74
|
+
enableTelemetry,
|
|
75
|
+
fetchCredentials,
|
|
76
|
+
speechRecognitionEndpointId,
|
|
77
|
+
speechRecognitionLanguage,
|
|
78
|
+
speechSynthesisDeploymentId,
|
|
79
|
+
speechSynthesisOutputFormat,
|
|
80
|
+
textNormalization,
|
|
81
|
+
userID,
|
|
82
|
+
username
|
|
83
|
+
});
|
|
84
|
+
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { createStyleSet } from 'botframework-webchat-component';
|
|
2
|
-
import { StyleOptions } from 'botframework-webchat-api';
|
|
3
2
|
|
|
4
3
|
import createAdaptiveCardsStyleSet from './adaptiveCards/Styles/createAdaptiveCardsStyleSet';
|
|
4
|
+
import FullBundleStyleOptions from './types/FullBundleStyleOptions';
|
|
5
5
|
|
|
6
6
|
// TODO: [P4] We should add a notice for people who want to use "styleSet" instead of "styleOptions".
|
|
7
7
|
// "styleSet" is actually CSS stylesheet and it is based on the DOM tree.
|
|
8
8
|
// DOM tree may change from time to time, thus, maintaining "styleSet" becomes a constant effort.
|
|
9
9
|
|
|
10
|
-
export default function createFullStyleSet(options:
|
|
10
|
+
export default function createFullStyleSet(options: FullBundleStyleOptions) {
|
|
11
11
|
return {
|
|
12
12
|
...createStyleSet(options),
|
|
13
13
|
...createAdaptiveCardsStyleSet(options)
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { defaultStyleOptions } from 'botframework-webchat-api';
|
|
2
2
|
import adaptiveCardsDefaultStyleOptions from './adaptiveCards/defaultStyleOptions';
|
|
3
3
|
|
|
4
|
-
import FullBundleStyleOptions from './FullBundleStyleOptions';
|
|
4
|
+
import FullBundleStyleOptions from './types/FullBundleStyleOptions';
|
|
5
5
|
|
|
6
|
-
const
|
|
6
|
+
const fullBundleDefaultStyleOptions: Required<FullBundleStyleOptions> = {
|
|
7
7
|
...defaultStyleOptions,
|
|
8
8
|
...adaptiveCardsDefaultStyleOptions
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
-
export default
|
|
11
|
+
export default fullBundleDefaultStyleOptions;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { hooks } from 'botframework-webchat-component';
|
|
2
|
+
|
|
3
|
+
import { StrictFullBundleStyleOptions } from '../types/FullBundleStyleOptions';
|
|
4
|
+
|
|
5
|
+
export default function useStyleOptions(): [StrictFullBundleStyleOptions] {
|
|
6
|
+
const [styleOptions] = hooks.useStyleOptions();
|
|
7
|
+
|
|
8
|
+
return [styleOptions as StrictFullBundleStyleOptions];
|
|
9
|
+
}
|
package/src/index-es5.ts
CHANGED
package/src/index-minimal.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
// IMPORTANT: To export anything from this file, add it to index-minimal.tsx, which is the .d.ts for this file.
|
|
2
|
-
|
|
3
1
|
/* eslint dot-notation: ["error", { "allowPattern": "^WebChat$" }] */
|
|
4
2
|
// window['WebChat'] is required for TypeScript
|
|
5
3
|
|
|
6
4
|
import { Constants, createStore, createStoreWithDevTools, version } from 'botframework-webchat-core';
|
|
5
|
+
import { StrictStyleOptions, StyleOptions } from 'botframework-webchat-api';
|
|
7
6
|
|
|
8
7
|
import ReactWebChat, {
|
|
9
8
|
Components,
|
|
@@ -55,6 +54,8 @@ export {
|
|
|
55
54
|
version
|
|
56
55
|
};
|
|
57
56
|
|
|
57
|
+
export type { StyleOptions, StrictStyleOptions };
|
|
58
|
+
|
|
58
59
|
// Until we have a development-specific bundle, we are not shipping createStoreWithDevTools in bundle.
|
|
59
60
|
window['WebChat'] = {
|
|
60
61
|
...window['WebChat'],
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
// IMPORTANT: To export anything from this file, add it to index.tsx, which is the .d.ts for this file.
|
|
2
|
-
|
|
3
1
|
/* eslint dot-notation: ["error", { "allowPattern": "^WebChat$" }] */
|
|
4
2
|
// window['WebChat'] is required for TypeScript
|
|
5
3
|
|
|
@@ -18,6 +16,7 @@ import createDirectLineSpeechAdapters from './createDirectLineSpeechAdapters';
|
|
|
18
16
|
import createStyleSet from './createFullStyleSet';
|
|
19
17
|
import defaultCreateDirectLine from './createDirectLine';
|
|
20
18
|
import defaultCreateDirectLineAppServiceExtension from './createDirectLineAppServiceExtension';
|
|
19
|
+
import FullBundleStyleOptions, { StrictFullBundleStyleOptions } from './types/FullBundleStyleOptions';
|
|
21
20
|
import FullComposer from './FullComposer';
|
|
22
21
|
import HeroCardContent from './adaptiveCards/Attachment/HeroCardContent';
|
|
23
22
|
import OAuthCardContent from './adaptiveCards/Attachment/OAuthCardContent';
|
|
@@ -28,12 +27,13 @@ import SignInCardContent from './adaptiveCards/Attachment/SignInCardContent';
|
|
|
28
27
|
import ThumbnailCardContent from './adaptiveCards/Attachment/ThumbnailCardContent';
|
|
29
28
|
import useAdaptiveCardsHostConfig from './adaptiveCards/hooks/useAdaptiveCardsHostConfig';
|
|
30
29
|
import useAdaptiveCardsPackage from './adaptiveCards/hooks/useAdaptiveCardsPackage';
|
|
30
|
+
import useStyleOptions from './hooks/useStyleOptions';
|
|
31
31
|
import VideoCardContent from './adaptiveCards/Attachment/VideoCardContent';
|
|
32
32
|
|
|
33
33
|
const renderWebChat = coreRenderWebChat.bind(null, ReactWebChat);
|
|
34
34
|
|
|
35
|
-
export const createDirectLine = options => {
|
|
36
|
-
options.botAgent &&
|
|
35
|
+
export const createDirectLine = (options: Omit<Parameters<typeof defaultCreateDirectLine>[0], 'botAgent'>) => {
|
|
36
|
+
(options as any).botAgent &&
|
|
37
37
|
console.warn(
|
|
38
38
|
'Web Chat: Developers are not currently allowed to set botAgent. See https://github.com/microsoft/BotFramework-WebChat/issues/2119 for more details.'
|
|
39
39
|
);
|
|
@@ -41,8 +41,10 @@ export const createDirectLine = options => {
|
|
|
41
41
|
return defaultCreateDirectLine({ ...options, botAgent: `WebChat/${version} (Full)` });
|
|
42
42
|
};
|
|
43
43
|
|
|
44
|
-
export const createDirectLineAppServiceExtension =
|
|
45
|
-
options
|
|
44
|
+
export const createDirectLineAppServiceExtension = (
|
|
45
|
+
options: Omit<Parameters<typeof defaultCreateDirectLineAppServiceExtension>[0], 'botAgent'>
|
|
46
|
+
) => {
|
|
47
|
+
(options as any).botAgent &&
|
|
46
48
|
console.warn(
|
|
47
49
|
'Web Chat: Developers are not currently allowed to set botAgent. See https://github.com/microsoft/BotFramework-WebChat/issues/2119 for more details.'
|
|
48
50
|
);
|
|
@@ -53,14 +55,14 @@ export const createDirectLineAppServiceExtension = options => {
|
|
|
53
55
|
const patchedHooks = {
|
|
54
56
|
...hooks,
|
|
55
57
|
useAdaptiveCardsHostConfig,
|
|
56
|
-
useAdaptiveCardsPackage
|
|
58
|
+
useAdaptiveCardsPackage,
|
|
59
|
+
useStyleOptions
|
|
57
60
|
};
|
|
58
61
|
|
|
59
|
-
const
|
|
60
|
-
...MinimalComponents,
|
|
62
|
+
const AdditionalComponents = {
|
|
61
63
|
AdaptiveCardContent,
|
|
62
|
-
AudioCardContent,
|
|
63
64
|
AnimationCardContent,
|
|
65
|
+
AudioCardContent,
|
|
64
66
|
Composer: FullComposer,
|
|
65
67
|
HeroCardContent,
|
|
66
68
|
OAuthCardContent,
|
|
@@ -70,6 +72,14 @@ const Components = {
|
|
|
70
72
|
VideoCardContent
|
|
71
73
|
};
|
|
72
74
|
|
|
75
|
+
const Components: typeof MinimalComponents & typeof AdditionalComponents = {
|
|
76
|
+
...MinimalComponents,
|
|
77
|
+
...AdditionalComponents
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
type StyleOptions = FullBundleStyleOptions;
|
|
81
|
+
type StrictStyleOptions = StrictFullBundleStyleOptions;
|
|
82
|
+
|
|
73
83
|
export default ReactWebChat;
|
|
74
84
|
|
|
75
85
|
export {
|
|
@@ -84,6 +94,8 @@ export {
|
|
|
84
94
|
renderWebChat
|
|
85
95
|
};
|
|
86
96
|
|
|
97
|
+
export type { StyleOptions, StrictStyleOptions };
|
|
98
|
+
|
|
87
99
|
window['WebChat'] = {
|
|
88
100
|
...window['WebChat'],
|
|
89
101
|
Components,
|
|
@@ -57,7 +57,11 @@ const TRANSPARENT_GIF = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAA
|
|
|
57
57
|
// This is used for parsing Markdown for external links.
|
|
58
58
|
const internalMarkdownIt = new MarkdownIt();
|
|
59
59
|
|
|
60
|
-
export default function render(
|
|
60
|
+
export default function render(
|
|
61
|
+
markdown: string,
|
|
62
|
+
{ markdownRespectCRLF }: { markdownRespectCRLF: boolean },
|
|
63
|
+
{ externalLinkAlt = '' }: { externalLinkAlt?: string } = {}
|
|
64
|
+
): string {
|
|
61
65
|
if (markdownRespectCRLF) {
|
|
62
66
|
markdown = markdown.replace(/\n\r|\r\n/gu, carriageReturn => (carriageReturn === '\n\r' ? '\r\n' : '\n\r'));
|
|
63
67
|
}
|
|
@@ -93,5 +97,8 @@ export default function render(markdown, { markdownRespectCRLF }, { externalLink
|
|
|
93
97
|
})
|
|
94
98
|
.render(markdown);
|
|
95
99
|
|
|
100
|
+
// The signature from "sanitize-html" module is not correct.
|
|
101
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
102
|
+
// @ts-ignore
|
|
96
103
|
return sanitizeHTML(html, SANITIZE_HTML_OPTIONS);
|
|
97
104
|
}
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
import { AudioInputStream } from 'microsoft-cognitiveservices-speech-sdk';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
AudioSourceErrorEvent,
|
|
5
|
+
AudioSourceEvent,
|
|
6
|
+
AudioSourceInitializingEvent,
|
|
7
|
+
AudioSourceOffEvent,
|
|
8
|
+
AudioSourceReadyEvent,
|
|
9
|
+
AudioStreamNodeAttachedEvent,
|
|
10
|
+
AudioStreamNodeAttachingEvent,
|
|
11
|
+
AudioStreamNodeDetachedEvent,
|
|
12
|
+
AudioStreamNodeErrorEvent,
|
|
13
|
+
Events,
|
|
14
|
+
EventSource
|
|
15
|
+
} from 'microsoft-cognitiveservices-speech-sdk/distrib/lib/src/common/Exports';
|
|
16
|
+
|
|
17
|
+
import { AudioStreamFormatImpl } from 'microsoft-cognitiveservices-speech-sdk/distrib/lib/src/sdk/Audio/AudioStreamFormat';
|
|
18
|
+
|
|
19
|
+
import {
|
|
20
|
+
connectivity as Connectivity,
|
|
21
|
+
ISpeechConfigAudioDevice,
|
|
22
|
+
type as Type
|
|
23
|
+
} from 'microsoft-cognitiveservices-speech-sdk/distrib/lib/src/common.speech/Exports';
|
|
24
|
+
|
|
25
|
+
import { v4 } from 'uuid';
|
|
26
|
+
import createDeferred, { DeferredPromise } from 'p-defer-es5';
|
|
27
|
+
|
|
28
|
+
type AudioStreamNode = {
|
|
29
|
+
detach: () => Promise<void>;
|
|
30
|
+
id: () => string;
|
|
31
|
+
read: () => Promise<StreamChunk<ArrayBuffer>>;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
type DeviceInfo = {
|
|
35
|
+
connectivity?: Connectivity | 'Bluetooth' | 'Wired' | 'WiFi' | 'Cellular' | 'InBuilt' | 'Unknown';
|
|
36
|
+
manufacturer?: string;
|
|
37
|
+
model?: string;
|
|
38
|
+
type?:
|
|
39
|
+
| Type
|
|
40
|
+
| 'Phone'
|
|
41
|
+
| 'Speaker'
|
|
42
|
+
| 'Car'
|
|
43
|
+
| 'Headset'
|
|
44
|
+
| 'Thermostat'
|
|
45
|
+
| 'Microphones'
|
|
46
|
+
| 'Deskphone'
|
|
47
|
+
| 'RemoteControl'
|
|
48
|
+
| 'Unknown'
|
|
49
|
+
| 'File'
|
|
50
|
+
| 'Stream';
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
type Format = {
|
|
54
|
+
bitsPerSample: number;
|
|
55
|
+
channels: number;
|
|
56
|
+
samplesPerSec: number;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
type NormalizedOptions = Required<Omit<Options, 'debug'>> & {
|
|
60
|
+
debug: boolean;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
type Options = {
|
|
64
|
+
debug?: true;
|
|
65
|
+
id?: string;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
type StreamChunk<T> = {
|
|
69
|
+
isEnd: boolean;
|
|
70
|
+
buffer: T;
|
|
71
|
+
timeReceived: number;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const SYMBOL_DEVICE_INFO_DEFERRED = Symbol('deviceInfoDeferred');
|
|
75
|
+
const SYMBOL_EVENTS = Symbol('events');
|
|
76
|
+
const SYMBOL_FORMAT_DEFERRED = Symbol('formatDeferred');
|
|
77
|
+
const SYMBOL_OPTIONS = Symbol('options');
|
|
78
|
+
|
|
79
|
+
// Speech SDK quirks: Only 2 lifecycle functions are actually used.
|
|
80
|
+
// They are: attach() and turnOff().
|
|
81
|
+
// Others are not used, including: blob(), close(), detach(), turnOn().
|
|
82
|
+
abstract class CustomAudioInputStream extends AudioInputStream {
|
|
83
|
+
constructor(options: Options = {}) {
|
|
84
|
+
super();
|
|
85
|
+
|
|
86
|
+
const normalizedOptions: NormalizedOptions = {
|
|
87
|
+
debug: options.debug || false,
|
|
88
|
+
id: options.id || v4().replace(/-/gu, '')
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
this[SYMBOL_DEVICE_INFO_DEFERRED] = createDeferred<DeviceInfo>();
|
|
92
|
+
this[SYMBOL_EVENTS] = new EventSource<AudioSourceEvent>();
|
|
93
|
+
this[SYMBOL_FORMAT_DEFERRED] = createDeferred<AudioStreamFormatImpl>();
|
|
94
|
+
this[SYMBOL_OPTIONS] = normalizedOptions;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
[SYMBOL_DEVICE_INFO_DEFERRED]: DeferredPromise<DeviceInfo>;
|
|
98
|
+
[SYMBOL_EVENTS]: EventSource<AudioSourceEvent>;
|
|
99
|
+
[SYMBOL_FORMAT_DEFERRED]: DeferredPromise<AudioStreamFormatImpl>;
|
|
100
|
+
[SYMBOL_OPTIONS]: NormalizedOptions;
|
|
101
|
+
|
|
102
|
+
/** Gets the event source for listening to events. */
|
|
103
|
+
// ESLint: This code will only works in browsers other than IE11. Only works in ES5 is okay.
|
|
104
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
105
|
+
// @ts-ignore Accessors are only available when targeting ECMAScript 5 and higher.ts(1056)
|
|
106
|
+
get events(): EventSource<AudioSourceEvent> {
|
|
107
|
+
return this[SYMBOL_EVENTS];
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** Gets the format of the audio stream. */
|
|
111
|
+
// Speech SDK quirks: `AudioStreamFormatImpl` is internal implementation while `AudioStreamFormat` is public.
|
|
112
|
+
// It is weird to expose `AudioStreamFormatImpl` instead of `AudioStreamFormat`.
|
|
113
|
+
// Speech SDK quirks: It is weird to return a `Promise` in a property.
|
|
114
|
+
// Speech SDK quirks: In normal speech recognition, getter of "format" is called only after "attach".
|
|
115
|
+
// But in Direct Line Speech, it is called before "attach".
|
|
116
|
+
// ESLint: This code will only works in browsers other than IE11. Only works in ES5 is okay.
|
|
117
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
118
|
+
// @ts-ignore Accessors are only available when targeting ECMAScript 5 and higher.ts(1056)
|
|
119
|
+
get format(): Promise<AudioStreamFormatImpl> {
|
|
120
|
+
this.debug('Getting "format".');
|
|
121
|
+
|
|
122
|
+
return this[SYMBOL_FORMAT_DEFERRED].promise;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** Gets the ID of this audio stream. */
|
|
126
|
+
id(): string {
|
|
127
|
+
return this[SYMBOL_OPTIONS].id;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/** Emits an event. */
|
|
131
|
+
// Speech SDK quirks: In JavaScript, onXxx means "listen to event XXX".
|
|
132
|
+
// Instead, in Speech SDK, it means "emit event XXX".
|
|
133
|
+
protected onEvent(event: AudioSourceEvent): void {
|
|
134
|
+
this[SYMBOL_EVENTS].onEvent(event);
|
|
135
|
+
Events.instance.onEvent(event);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** Emits an `AudioSourceInitializingEvent`. */
|
|
139
|
+
protected emitInitializing(): void {
|
|
140
|
+
this.debug('Emitting "AudioSourceInitializingEvent".');
|
|
141
|
+
this.onEvent(new AudioSourceInitializingEvent(this.id()));
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/** Emits an `AudioSourceReadyEvent`. */
|
|
145
|
+
protected emitReady(): void {
|
|
146
|
+
this.debug('Emitting "AudioSourceReadyEvent".');
|
|
147
|
+
this.onEvent(new AudioSourceReadyEvent(this.id()));
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/** Emits an `AudioSourceErrorEvent`. */
|
|
151
|
+
// Speech SDK quirks: Since "turnOn" is never called and "turnOff" does not work in Direct Line Speech, the "source error" event is not emitted at all.
|
|
152
|
+
// Instead, we only emit "node error" event.
|
|
153
|
+
protected emitError(error: Error): void {
|
|
154
|
+
this.debug('Emitting "AudioSourceErrorEvent".', { error });
|
|
155
|
+
|
|
156
|
+
// Speech SDK quirks: "error" is a string, instead of object of type "Error".
|
|
157
|
+
this.onEvent(new AudioSourceErrorEvent(this.id(), error.message));
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/** Emits an `AudioStreamNodeAttachingEvent`. */
|
|
161
|
+
protected emitNodeAttaching(audioNodeId: string): void {
|
|
162
|
+
this.debug(`Emitting "AudioStreamNodeAttachingEvent" for node "${audioNodeId}".`);
|
|
163
|
+
this.onEvent(new AudioStreamNodeAttachingEvent(this.id(), audioNodeId));
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/** Emits an `AudioStreamNodeAttachedEvent`. */
|
|
167
|
+
protected emitNodeAttached(audioNodeId: string): void {
|
|
168
|
+
this.debug(`Emitting "AudioStreamNodeAttachedEvent" for node "${audioNodeId}".`);
|
|
169
|
+
this.onEvent(new AudioStreamNodeAttachedEvent(this.id(), audioNodeId));
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/** Emits an `AudioStreamNodeErrorEvent`. */
|
|
173
|
+
protected emitNodeError(audioNodeId: string, error: Error): void {
|
|
174
|
+
this.debug(`Emitting "AudioStreamNodeErrorEvent" for node "${audioNodeId}".`, { error });
|
|
175
|
+
|
|
176
|
+
// Speech SDK quirks: "error" is a string, instead of object of type "Error".
|
|
177
|
+
this.onEvent(new AudioStreamNodeErrorEvent(this.id(), audioNodeId, error.message));
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/** Emits an `AudioStreamNodeDetachedEvent`. */
|
|
181
|
+
protected emitNodeDetached(audioNodeId: string): void {
|
|
182
|
+
this.debug('Emitting "AudioStreamNodeDetachedEvent".');
|
|
183
|
+
this.onEvent(new AudioStreamNodeDetachedEvent(this.id(), audioNodeId));
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/** Emits an `AudioSourceOffEvent`. */
|
|
187
|
+
protected emitOff(): void {
|
|
188
|
+
this.debug('Emitting "AudioSourceOffEvent".');
|
|
189
|
+
this.onEvent(new AudioSourceOffEvent(this.id()));
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Speech SDK quirks: Although "close" is marked as abstract, it is never called in our observations.
|
|
193
|
+
// ESLint: Speech SDK requires this function, but we are not implementing it.
|
|
194
|
+
// eslint-disable-next-line class-methods-use-this
|
|
195
|
+
close(): void {
|
|
196
|
+
this.debug('Callback for "close".');
|
|
197
|
+
|
|
198
|
+
throw new Error('Not implemented');
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Speech SDK quirks: Although "turnOn" is implemented in Speech SDK Push/PullAudioInputStream, it is never called in our observations.
|
|
202
|
+
turnOn(): void {
|
|
203
|
+
this.debug('Callback for "turnOn".');
|
|
204
|
+
|
|
205
|
+
throw new Error('Not implemented');
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Speech SDK quirks: Although "detach" is implemented in Speech SDK Push/PullAudioInputStream, it is never called in our observations.
|
|
209
|
+
detach(): void {
|
|
210
|
+
this.debug('Callback for "detach".');
|
|
211
|
+
|
|
212
|
+
throw new Error('Not implemented');
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/** Log the message to console if `debug` is set to `true`. */
|
|
216
|
+
private debug(message, ...args) {
|
|
217
|
+
// ESLint: For debugging, will only log when "debug" is set to "true".
|
|
218
|
+
// eslint-disable-next-line no-console
|
|
219
|
+
this[SYMBOL_OPTIONS].debug && console.info(`CustomAudioInputStream: ${message}`, ...args);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/** Implements this function. When called, it should start recording and return an `IAudioStreamNode`. */
|
|
223
|
+
protected abstract performAttach(audioNodeId: string): Promise<{
|
|
224
|
+
audioStreamNode: AudioStreamNode;
|
|
225
|
+
deviceInfo: DeviceInfo;
|
|
226
|
+
format: Format;
|
|
227
|
+
}>;
|
|
228
|
+
|
|
229
|
+
/** Attaches the device by returning an audio node. */
|
|
230
|
+
attach(audioNodeId: string): Promise<AudioStreamNode> {
|
|
231
|
+
this.debug(`Callback for "attach" with "${audioNodeId}".`);
|
|
232
|
+
|
|
233
|
+
this.emitNodeAttaching(audioNodeId);
|
|
234
|
+
|
|
235
|
+
return Promise.resolve().then<AudioStreamNode>(async () => {
|
|
236
|
+
this.emitInitializing();
|
|
237
|
+
|
|
238
|
+
try {
|
|
239
|
+
const { audioStreamNode, deviceInfo, format } = await this.performAttach(audioNodeId);
|
|
240
|
+
|
|
241
|
+
// Although only getter of "format" is called before "attach" (in Direct Line Speech),
|
|
242
|
+
// we are handling both "deviceInfo" and "format" in similar way for uniformity.
|
|
243
|
+
this[SYMBOL_DEVICE_INFO_DEFERRED].resolve(deviceInfo);
|
|
244
|
+
this[SYMBOL_FORMAT_DEFERRED].resolve(
|
|
245
|
+
new AudioStreamFormatImpl(format.samplesPerSec, format.bitsPerSample, format.channels)
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
this.emitReady();
|
|
249
|
+
this.emitNodeAttached(audioNodeId);
|
|
250
|
+
|
|
251
|
+
return {
|
|
252
|
+
detach: async () => {
|
|
253
|
+
this.debug(`Detaching audio node "${audioNodeId}".`);
|
|
254
|
+
|
|
255
|
+
await audioStreamNode.detach();
|
|
256
|
+
|
|
257
|
+
// Speech SDK quirks: Since "turnOff" is not called in Direct Line Speech, we will emit event "source off" here instead.
|
|
258
|
+
this.emitOff();
|
|
259
|
+
this.emitNodeDetached(audioNodeId);
|
|
260
|
+
},
|
|
261
|
+
id: () => audioStreamNode.id(),
|
|
262
|
+
read: () => {
|
|
263
|
+
this.debug('Reading');
|
|
264
|
+
|
|
265
|
+
return audioStreamNode.read();
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
} catch (error) {
|
|
269
|
+
this.emitNodeError(audioNodeId, error);
|
|
270
|
+
|
|
271
|
+
throw error;
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Implements this function. When called, it should stop recording. This is called before the `IAudioStreamNode.detach` function.
|
|
278
|
+
*
|
|
279
|
+
* Note: when using with Direct Line Speech, this function is never called.
|
|
280
|
+
*/
|
|
281
|
+
|
|
282
|
+
// ESLint: We are not implementing this function because it is not called by Direct Line Speech.
|
|
283
|
+
// eslint-disable-next-line class-methods-use-this
|
|
284
|
+
protected performTurnOff(): Promise<void> {
|
|
285
|
+
// ESLint: "return" is required by TypeScript
|
|
286
|
+
// eslint-disable-next-line no-useless-return
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/** Turn off the audio device. This is called before detaching from the graph. */
|
|
291
|
+
// Speech SDK quirks: It is confused to have both "turnOff" and "detach". "turnOff" is called before "detach".
|
|
292
|
+
// Why don't we put all logics at "detach"?
|
|
293
|
+
// Speech SDK quirks: Direct Line Speech never call "turnOff". "Source off" event need to be emitted during "detach" instead.
|
|
294
|
+
// Also, custom implementation should be done at "detach" instead, such as ending and closing output streams.
|
|
295
|
+
async turnOff(): Promise<void> {
|
|
296
|
+
this.debug(`Callback for "turnOff".`);
|
|
297
|
+
|
|
298
|
+
await this.performTurnOff();
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/** Gets the device information. */
|
|
302
|
+
// ESLint: This code will only works in browsers other than IE11. Only works in ES5 is okay.
|
|
303
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
304
|
+
// @ts-ignore Accessors are only available when targeting ECMAScript 5 and higher.ts(1056)
|
|
305
|
+
get deviceInfo(): Promise<ISpeechConfigAudioDevice> {
|
|
306
|
+
this.debug(`Getting "deviceInfo".`);
|
|
307
|
+
|
|
308
|
+
return Promise.all([this[SYMBOL_DEVICE_INFO_DEFERRED].promise, this[SYMBOL_FORMAT_DEFERRED].promise]).then(
|
|
309
|
+
([{ connectivity, manufacturer, model, type }, { bitsPerSample, channels, samplesPerSec }]) => ({
|
|
310
|
+
bitspersample: bitsPerSample,
|
|
311
|
+
channelcount: channels,
|
|
312
|
+
connectivity:
|
|
313
|
+
typeof connectivity === 'string' ? Connectivity[connectivity] : connectivity || Connectivity.Unknown,
|
|
314
|
+
manufacturer: manufacturer || '',
|
|
315
|
+
model: model || '',
|
|
316
|
+
samplerate: samplesPerSec,
|
|
317
|
+
type: typeof type === 'string' ? Type[type] : type || Type.Unknown
|
|
318
|
+
})
|
|
319
|
+
);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
export default CustomAudioInputStream;
|
|
324
|
+
|
|
325
|
+
export type { AudioStreamNode, DeviceInfo, Format, Options };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/* eslint @typescript-eslint/no-empty-function: "off" */
|
|
2
|
+
|
|
3
|
+
import createAudioConfig from './createAudioConfig';
|
|
4
|
+
|
|
5
|
+
describe('Verify arguments', () => {
|
|
6
|
+
test('should not throw if only "attach" is supplied', () => {
|
|
7
|
+
expect(() => createAudioConfig({ attach: () => {} })).not.toThrow();
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
test('should not throw if both "attach" and "turnOff" are supplied', () => {
|
|
11
|
+
expect(() => createAudioConfig({ attach: () => {}, turnOff: () => {} })).not.toThrow();
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test('should throw if "attach" is not supplied', () => {
|
|
15
|
+
expect(() => createAudioConfig({})).toThrow('"attach" must be a function.');
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test('should throw if "turnOff" is not a function', () => {
|
|
19
|
+
expect(() => createAudioConfig({ attach: () => {}, turnOff: '123' })).toThrow(
|
|
20
|
+
'"turnOff", if defined, must be a function.'
|
|
21
|
+
);
|
|
22
|
+
});
|
|
23
|
+
});
|