Convert to using ESLint for static code analysis (#498)
* Initial cleanup, 1884 errors remaining * use async cancelSpeech synchronously in callback * fix synthvoiceresult constructor * fix IInternalParticipant to add members forgotten in original implementation, more lint fixes * turn off member ordering, more fixes for linter * down to 1301 problems (but inferred types ain't one). * 1254 errors * more lints * lint progress checkin * 989 problems * 899 errors * milestone checkin * add IActivity interface * milestone checkin * milestone checkin * 425 errors * milestone checkin < 400 errors * milestone checkin * 224 errors * 194 errors * 94 issues * CertChecks passes lint without breaking tests * all src files pass eslint * fix build issues, allow eslint to fail build * package changes for build * og package lock * retry build * different import order for certchecks * revert cert_checks * see if this builds * testing url-parse removal * Use more complete WordResult interface * More correct IActivity interface * add hostname to options in CertChecks
This commit is contained in:
Родитель
fa96b1a603
Коммит
6c070c429f
|
@ -0,0 +1,265 @@
|
|||
/*
|
||||
👋 Hi! This file was autogenerated by tslint-to-eslint-config.
|
||||
https://github.com/typescript-eslint/tslint-to-eslint-config
|
||||
|
||||
It represents the closest reasonable ESLint configuration to this
|
||||
project's original TSLint configuration.
|
||||
|
||||
We recommend eventually switching this configuration to extend from
|
||||
the recommended rulesets in typescript-eslint.
|
||||
https://github.com/typescript-eslint/tslint-to-eslint-config/blob/master/docs/FAQs.md
|
||||
|
||||
Happy linting! 💖
|
||||
*/
|
||||
module.exports = {
|
||||
"env": {
|
||||
"browser": true,
|
||||
"node": true
|
||||
},
|
||||
"extends": [
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:@typescript-eslint/recommended-requiring-type-checking"
|
||||
],
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"project": "tsconfig.json",
|
||||
"sourceType": "module"
|
||||
},
|
||||
"plugins": [
|
||||
"eslint-plugin-prefer-arrow",
|
||||
"eslint-plugin-jsdoc",
|
||||
"eslint-plugin-import",
|
||||
"@typescript-eslint",
|
||||
"@typescript-eslint/tslint"
|
||||
],
|
||||
"rules": {
|
||||
"@typescript-eslint/adjacent-overload-signatures": "error",
|
||||
"@typescript-eslint/array-type": [
|
||||
"error",
|
||||
{
|
||||
"default": "array"
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/ban-types": [
|
||||
"error",
|
||||
{
|
||||
"types": {
|
||||
"Object": {
|
||||
"message": "Avoid using the `Object` type. Did you mean `object`?"
|
||||
},
|
||||
"Function": {
|
||||
"message": "Avoid using the `Function` type. Prefer a specific function type, like `() => void`."
|
||||
},
|
||||
"Boolean": {
|
||||
"message": "Avoid using the `Boolean` type. Did you mean `boolean`?"
|
||||
},
|
||||
"Number": {
|
||||
"message": "Avoid using the `Number` type. Did you mean `number`?"
|
||||
},
|
||||
"String": {
|
||||
"message": "Avoid using the `String` type. Did you mean `string`?"
|
||||
},
|
||||
"Symbol": {
|
||||
"message": "Avoid using the `Symbol` type. Did you mean `symbol`?"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/consistent-type-assertions": "error",
|
||||
"@typescript-eslint/consistent-type-definitions": "error",
|
||||
"@typescript-eslint/dot-notation": "error",
|
||||
"@typescript-eslint/explicit-function-return-type": [
|
||||
"error",
|
||||
{
|
||||
"allowExpressions": false,
|
||||
"allowTypedFunctionExpressions": false,
|
||||
"allowHigherOrderFunctions": false,
|
||||
"allowDirectConstAssertionInArrowFunctions": true,
|
||||
"allowConciseArrowFunctionExpressionsStartingWithVoid": true
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/explicit-member-accessibility": [
|
||||
"error",
|
||||
{
|
||||
"accessibility": "explicit"
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/explicit-module-boundary-types": [
|
||||
"error",
|
||||
{
|
||||
"allowArgumentsExplicitlyTypedAsAny": true,
|
||||
"allowDirectConstAssertionInArrowFunctions": true,
|
||||
"allowHigherOrderFunctions": false,
|
||||
"allowTypedFunctionExpressions": false
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/member-delimiter-style": [
|
||||
"error",
|
||||
{
|
||||
"multiline": {
|
||||
"delimiter": "semi",
|
||||
"requireLast": true
|
||||
},
|
||||
"singleline": {
|
||||
"delimiter": "semi",
|
||||
"requireLast": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/member-ordering": "off",
|
||||
"@typescript-eslint/naming-convention": "off",
|
||||
"@typescript-eslint/no-empty-function": "error",
|
||||
"@typescript-eslint/no-empty-interface": "error",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/no-floating-promises": "error",
|
||||
"@typescript-eslint/no-inferrable-types": "off",
|
||||
"@typescript-eslint/no-misused-new": "error",
|
||||
"@typescript-eslint/no-namespace": "error",
|
||||
"@typescript-eslint/no-parameter-properties": "off",
|
||||
"@typescript-eslint/no-shadow": [
|
||||
"off",
|
||||
{
|
||||
"hoist": "all"
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/no-unused-expressions": "error",
|
||||
"@typescript-eslint/no-use-before-define": "off",
|
||||
"@typescript-eslint/no-var-requires": "error",
|
||||
"@typescript-eslint/prefer-for-of": "error",
|
||||
"@typescript-eslint/prefer-function-type": "error",
|
||||
"@typescript-eslint/prefer-namespace-keyword": "error",
|
||||
"@typescript-eslint/quotes": [
|
||||
"error",
|
||||
"double",
|
||||
{
|
||||
"avoidEscape": true
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/semi": [
|
||||
"error",
|
||||
"always"
|
||||
],
|
||||
"@typescript-eslint/triple-slash-reference": [
|
||||
"error",
|
||||
{
|
||||
"path": "always",
|
||||
"types": "prefer-import",
|
||||
"lib": "always"
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/type-annotation-spacing": "error",
|
||||
"@typescript-eslint/typedef": [
|
||||
"error",
|
||||
{
|
||||
"parameter": true,
|
||||
"arrowParameter": true,
|
||||
"propertyDeclaration": true,
|
||||
"memberVariableDeclaration": true
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/unified-signatures": "error",
|
||||
"arrow-body-style": "error",
|
||||
"arrow-parens": [
|
||||
"error",
|
||||
"always"
|
||||
],
|
||||
"brace-style": [
|
||||
"error",
|
||||
"1tbs"
|
||||
],
|
||||
"comma-dangle": "off",
|
||||
"complexity": "off",
|
||||
"constructor-super": "error",
|
||||
"curly": "error",
|
||||
"dot-notation": "error",
|
||||
"eol-last": "error",
|
||||
"eqeqeq": [
|
||||
"error",
|
||||
"smart"
|
||||
],
|
||||
"guard-for-in": "error",
|
||||
"id-match": "error",
|
||||
"import/order": "error",
|
||||
"jsdoc/check-alignment": "error",
|
||||
"jsdoc/check-indentation": "error",
|
||||
"max-classes-per-file": [
|
||||
"error",
|
||||
1
|
||||
],
|
||||
"max-len": "off",
|
||||
"new-parens": "error",
|
||||
"no-bitwise": "off",
|
||||
"no-caller": "error",
|
||||
"no-cond-assign": "error",
|
||||
"no-console": "error",
|
||||
"no-debugger": "error",
|
||||
"no-empty": "error",
|
||||
"no-empty-function": "off",
|
||||
"no-eval": "error",
|
||||
"no-fallthrough": "off",
|
||||
"no-invalid-this": "off",
|
||||
"no-multiple-empty-lines": "error",
|
||||
"no-new-wrappers": "error",
|
||||
"no-shadow": "off",
|
||||
"no-throw-literal": "error",
|
||||
"no-trailing-spaces": "error",
|
||||
"no-undef-init": "error",
|
||||
"no-underscore-dangle": "error",
|
||||
"no-unsafe-finally": "error",
|
||||
"no-unused-expressions": "error",
|
||||
"no-unused-labels": "error",
|
||||
"no-use-before-define": "off",
|
||||
"no-var": "error",
|
||||
"object-shorthand": "error",
|
||||
"one-var": [
|
||||
"error",
|
||||
"never"
|
||||
],
|
||||
"prefer-arrow/prefer-arrow-functions": "error",
|
||||
"prefer-const": "error",
|
||||
"quote-props": [
|
||||
"error",
|
||||
"consistent-as-needed"
|
||||
],
|
||||
"quotes": "error",
|
||||
"radix": "error",
|
||||
"semi": "error",
|
||||
"space-before-function-paren": [
|
||||
"error",
|
||||
{
|
||||
"anonymous": "never",
|
||||
"asyncArrow": "always",
|
||||
"named": "never"
|
||||
}
|
||||
],
|
||||
"spaced-comment": [
|
||||
"error",
|
||||
"always",
|
||||
{
|
||||
"markers": [
|
||||
"/"
|
||||
]
|
||||
}
|
||||
],
|
||||
"use-isnan": "error",
|
||||
"valid-typeof": "off",
|
||||
"@typescript-eslint/tslint/config": [
|
||||
"error",
|
||||
{
|
||||
"rules": {
|
||||
"import-spacing": true,
|
||||
"object-literal-sort-keys": true,
|
||||
"whitespace": [
|
||||
true,
|
||||
"check-branch",
|
||||
"check-decl",
|
||||
"check-operator",
|
||||
"check-separator",
|
||||
"check-type",
|
||||
"check-typecast"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
20
gulpfile.js
20
gulpfile.js
|
@ -3,7 +3,7 @@
|
|||
var gulp = require('gulp');
|
||||
var ts = require('gulp-typescript');
|
||||
var sourcemaps = require('gulp-sourcemaps');
|
||||
var tslint = require('gulp-tslint');
|
||||
var eslint = require('gulp-eslint');
|
||||
var terser = require('gulp-terser');
|
||||
var rename = require('gulp-rename');
|
||||
var pump = require('pump');
|
||||
|
@ -20,13 +20,12 @@
|
|||
'src/**/*.ts',
|
||||
'microsoft.cognitiveservices.speech.sdk.ts'],
|
||||
{ base: '.' })
|
||||
.pipe(tslint({
|
||||
.pipe(eslint({
|
||||
formatter: 'prose',
|
||||
configuration: 'tslint.json'
|
||||
}))
|
||||
.pipe(tslint.report({
|
||||
summarizeFailureOutput: true
|
||||
configuration: 'eslint.json'
|
||||
}))
|
||||
.pipe(eslint.format())
|
||||
.pipe(eslint.failAfterError())
|
||||
.pipe(sourcemaps.init())
|
||||
.pipe(tsProject())
|
||||
.pipe(sourcemaps.write('.'))
|
||||
|
@ -41,13 +40,12 @@
|
|||
'src/**/*.ts',
|
||||
'microsoft.cognitiveservices.speech.sdk.ts'],
|
||||
{ base: '.' })
|
||||
.pipe(tslint({
|
||||
.pipe(eslint({
|
||||
formatter: 'prose',
|
||||
configuration: 'tslint.json'
|
||||
}))
|
||||
.pipe(tslint.report({
|
||||
summarizeFailureOutput: true
|
||||
configuration: 'eslint.json'
|
||||
}))
|
||||
.pipe(eslint.format())
|
||||
.pipe(eslint.failAfterError())
|
||||
.pipe(sourcemaps.init())
|
||||
.pipe(tsProject2015())
|
||||
.pipe(sourcemaps.write('.'))
|
||||
|
|
13
package.json
13
package.json
|
@ -56,16 +56,22 @@
|
|||
"@types/node": "^12.12.30",
|
||||
"@types/request": "^2.48.3",
|
||||
"@types/rimraf": "^3.0.0",
|
||||
"@types/url-parse": "^1.4.8",
|
||||
"@types/uuid": "^3.3.3",
|
||||
"@types/ws": "^6.0.4",
|
||||
"@typescript-eslint/eslint-plugin": "^5.13.0",
|
||||
"@typescript-eslint/eslint-plugin-tslint": "^5.13.0",
|
||||
"@typescript-eslint/parser": "^5.13.0",
|
||||
"asn1.js": "^5.2.0",
|
||||
"dts-bundle-webpack": "^1.0.2",
|
||||
"eslint": "^8.10.0",
|
||||
"eslint-plugin-import": "^2.25.4",
|
||||
"eslint-plugin-jsdoc": "^37.9.7",
|
||||
"eslint-plugin-prefer-arrow": "^1.2.3",
|
||||
"gulp": "^4.0.2",
|
||||
"gulp-rename": "^2.0.0",
|
||||
"gulp-sourcemaps": "^2.6.5",
|
||||
"gulp-terser": "^1.2.0",
|
||||
"gulp-tslint": "^8.1.4",
|
||||
"gulp-eslint": "^6.0.0",
|
||||
"gulp-typescript": "^5.0.1",
|
||||
"jest": "^26.0.1",
|
||||
"jest-junit": "^12.0.0",
|
||||
|
@ -83,7 +89,7 @@
|
|||
"build": "gulp compress && gulp build2015",
|
||||
"test": "npm run lint && npm run jest --coverage",
|
||||
"jest": "jest",
|
||||
"lint": "tslint -p tsconfig.json",
|
||||
"lint": "eslint -c .eslintrc.js --ext .ts src",
|
||||
"civersion": "node ci/version.js",
|
||||
"prepare": "npm run build",
|
||||
"preinstall": "npm install --package-lock-only --ignore-scripts --no-audit && npx npm-force-resolutions"
|
||||
|
@ -108,7 +114,6 @@
|
|||
"bent": "^7.3.12",
|
||||
"https-proxy-agent": "^4.0.0",
|
||||
"simple-lru-cache": "0.0.2",
|
||||
"url-parse": "^1.5.10",
|
||||
"uuid": "^8.3.0",
|
||||
"ws": "^7.5.6"
|
||||
},
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/* eslint-disable import/order */
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import * as http from "http";
|
||||
import * as tls from "tls";
|
||||
import * as parse from "url-parse";
|
||||
import * as ocsp from "../../external/ocsp/ocsp";
|
||||
import {
|
||||
Events,
|
||||
|
@ -28,12 +28,25 @@ import { ProxyInfo } from "./ProxyInfo";
|
|||
|
||||
import Agent from "agent-base";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
import Cache from "async-disk-cache";
|
||||
import HttpsProxyAgent from "https-proxy-agent";
|
||||
import * as net from "net";
|
||||
import { OCSPCacheUpdateErrorEvent } from "../common/OCSPEvents";
|
||||
|
||||
|
||||
interface tbsUpdateResponse {
|
||||
thisUpdate: number;
|
||||
nextUpdate: number;
|
||||
}
|
||||
|
||||
interface tbsResponse {
|
||||
tbsResponseData: {
|
||||
responses: tbsUpdateResponse[];
|
||||
};
|
||||
}
|
||||
|
||||
export class CertCheckAgent {
|
||||
|
||||
// Test hook to enable forcing expiration / refresh to happen.
|
||||
|
@ -50,13 +63,14 @@ export class CertCheckAgent {
|
|||
|
||||
private privProxyInfo: ProxyInfo;
|
||||
|
||||
constructor(proxyInfo?: ProxyInfo) {
|
||||
public constructor(proxyInfo?: ProxyInfo) {
|
||||
if (!!proxyInfo) {
|
||||
this.privProxyInfo = proxyInfo;
|
||||
}
|
||||
|
||||
// Initialize this here to allow tests to set the env variable before the cache is constructed.
|
||||
if (!CertCheckAgent.privDiskCache) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
|
||||
CertCheckAgent.privDiskCache = new Cache("microsoft-cognitiveservices-speech-sdk-cache", { supportBuffer: true, location: (typeof process !== "undefined" && !!process.env.SPEECH_OCSP_CACHE_ROOT) ? process.env.SPEECH_OCSP_CACHE_ROOT : undefined });
|
||||
}
|
||||
}
|
||||
|
@ -67,17 +81,20 @@ export class CertCheckAgent {
|
|||
CertCheckAgent.privMemCache = {};
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
public GetAgent(disableStapling?: boolean): http.Agent {
|
||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||
const agent: any = new Agent.Agent(this.CreateConnection);
|
||||
|
||||
if (this.privProxyInfo !== undefined &&
|
||||
this.privProxyInfo.HostName !== undefined &&
|
||||
this.privProxyInfo.Port > 0) {
|
||||
const proxyName: string = "privProxyInfo";
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
agent[proxyName] = this.privProxyInfo;
|
||||
}
|
||||
|
||||
return agent;
|
||||
return agent as http.Agent;
|
||||
}
|
||||
|
||||
private static GetProxyAgent(proxyInfo: ProxyInfo): HttpsProxyAgent {
|
||||
|
@ -88,7 +105,7 @@ export class CertCheckAgent {
|
|||
|
||||
if (!!proxyInfo.UserName) {
|
||||
httpProxyOptions.headers = {
|
||||
"Proxy-Authentication": "Basic " + new Buffer(proxyInfo.UserName + ":" + (proxyInfo.Password === undefined) ? "" : proxyInfo.Password).toString("base64"),
|
||||
"Proxy-Authentication": "Basic " + new Buffer(`${proxyInfo.UserName}:${(proxyInfo.Password === undefined) ? "" : proxyInfo.Password}`).toString("base64"),
|
||||
};
|
||||
} else {
|
||||
httpProxyOptions.headers = {};
|
||||
|
@ -110,7 +127,7 @@ export class CertCheckAgent {
|
|||
|
||||
const tlsSocket: tls.TLSSocket = socket as tls.TLSSocket;
|
||||
|
||||
return new Promise<net.Socket>((resolve: (value: net.Socket) => void, reject: (error: string | Error) => void) => {
|
||||
return new Promise<net.Socket>((resolve: (value: net.Socket) => void, reject: (error: string | Error) => void): void => {
|
||||
socket.on("OCSPResponse", (data: Buffer): void => {
|
||||
if (!!data) {
|
||||
this.onEvent(new OCSPStapleReceivedEvent());
|
||||
|
@ -118,7 +135,7 @@ export class CertCheckAgent {
|
|||
}
|
||||
});
|
||||
|
||||
socket.on("error", (error: Error) => {
|
||||
socket.on("error", (error: Error): void => {
|
||||
if (!resolved) {
|
||||
resolved = true;
|
||||
socket.destroy();
|
||||
|
@ -126,6 +143,7 @@ export class CertCheckAgent {
|
|||
}
|
||||
});
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises, @typescript-eslint/explicit-function-return-type
|
||||
tlsSocket.on("secure", async () => {
|
||||
const peer: tls.DetailedPeerCertificate = tlsSocket.getPeerCertificate(true);
|
||||
try {
|
||||
|
@ -151,7 +169,7 @@ export class CertCheckAgent {
|
|||
} catch (e) {
|
||||
socket.destroy();
|
||||
resolved = true;
|
||||
reject(e);
|
||||
reject(e as string);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -162,7 +180,7 @@ export class CertCheckAgent {
|
|||
return Promise.resolve(peer.issuerCertificate);
|
||||
}
|
||||
|
||||
return new Promise<tls.DetailedPeerCertificate>((resolve: (value: tls.DetailedPeerCertificate) => void, reject: (reason: string) => void) => {
|
||||
return new Promise<tls.DetailedPeerCertificate>((resolve: (value: tls.DetailedPeerCertificate) => void, reject: (reason: string) => void): void => {
|
||||
const ocspAgent: ocsp.Agent = new ocsp.Agent({});
|
||||
ocspAgent.fetchIssuer(peer, null, (error: string, value: tls.DetailedPeerCertificate): void => {
|
||||
if (!!error) {
|
||||
|
@ -185,7 +203,8 @@ export class CertCheckAgent {
|
|||
// Do we have a result for this certificate on disk in %TMP%?
|
||||
if (!cachedResponse) {
|
||||
try {
|
||||
const diskCacheResponse: any = await CertCheckAgent.privDiskCache.get(signature);
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
||||
const diskCacheResponse: { value: Buffer; isCached?: any } = await CertCheckAgent.privDiskCache.get(signature) as { value: Buffer; isCached?: any };
|
||||
if (!!diskCacheResponse.isCached) {
|
||||
CertCheckAgent.onEvent(new OCSPDiskCacheHitEvent(signature));
|
||||
CertCheckAgent.StoreMemoryCacheEntry(signature, diskCacheResponse.value);
|
||||
|
@ -202,7 +221,8 @@ export class CertCheckAgent {
|
|||
|
||||
try {
|
||||
const cachedOcspResponse: ocsp.Response = ocsp.utils.parseResponse(cachedResponse);
|
||||
const tbsData = cachedOcspResponse.value.tbsResponseData;
|
||||
const responseValue: tbsResponse = cachedOcspResponse.value as tbsResponse;
|
||||
const tbsData: { responses: tbsUpdateResponse[] } = responseValue.tbsResponseData;
|
||||
if (tbsData.responses.length < 1) {
|
||||
this.onEvent(new OCSPCacheFetchErrorEvent(signature, "Not enough data in cached response"));
|
||||
return;
|
||||
|
@ -223,7 +243,7 @@ export class CertCheckAgent {
|
|||
|
||||
if ((cachedNextTime - (Date.now() + this.testTimeOffset)) < minUpdate) {
|
||||
this.onEvent(new OCSPCacheEntryNeedsRefreshEvent(signature, cachedStartTime, cachedNextTime));
|
||||
this.UpdateCache(ocspRequest, proxyInfo).catch((error: string) => {
|
||||
this.UpdateCache(ocspRequest, proxyInfo).catch((error: string): void => {
|
||||
// Well, not much we can do here.
|
||||
this.onEvent(new OCSPCacheUpdateErrorEvent(signature, error.toString()));
|
||||
});
|
||||
|
@ -232,7 +252,7 @@ export class CertCheckAgent {
|
|||
}
|
||||
}
|
||||
} catch (error) {
|
||||
this.onEvent(new OCSPCacheFetchErrorEvent(signature, error));
|
||||
this.onEvent(new OCSPCacheFetchErrorEvent(signature, error as string));
|
||||
cachedResponse = null;
|
||||
}
|
||||
if (!cachedResponse) {
|
||||
|
@ -243,23 +263,22 @@ export class CertCheckAgent {
|
|||
|
||||
private static async VerifyOCSPResponse(cacheValue: Buffer, ocspRequest: ocsp.Request, proxyInfo: ProxyInfo): Promise<void> {
|
||||
let ocspResponse: Buffer = cacheValue;
|
||||
const sig: string = ocspRequest.certID.toString("hex");
|
||||
|
||||
// Do we have a valid response?
|
||||
if (!ocspResponse) {
|
||||
ocspResponse = await CertCheckAgent.GetOCSPResponse(ocspRequest, proxyInfo);
|
||||
}
|
||||
|
||||
return new Promise<void>((resolve: () => void, reject: (error: string | Error) => void) => {
|
||||
ocsp.verify({ request: ocspRequest, response: ocspResponse }, (error: string, result: any): void => {
|
||||
return new Promise<void>((resolve: () => void, reject: (error: string | Error) => void): void => {
|
||||
ocsp.verify({ request: ocspRequest, response: ocspResponse }, (error: string): void => {
|
||||
if (!!error) {
|
||||
CertCheckAgent.onEvent(new OCSPVerificationFailedEvent(ocspRequest.id.toString("hex"), error));
|
||||
|
||||
// Bad Cached Value? One more try without the cache.
|
||||
if (!!cacheValue) {
|
||||
this.VerifyOCSPResponse(null, ocspRequest, proxyInfo).then(() => {
|
||||
this.VerifyOCSPResponse(null, ocspRequest, proxyInfo).then((): void => {
|
||||
resolve();
|
||||
}, (error: Error) => {
|
||||
}, (error: Error): void => {
|
||||
reject(error);
|
||||
});
|
||||
} else {
|
||||
|
@ -296,7 +315,8 @@ export class CertCheckAgent {
|
|||
}
|
||||
|
||||
private static StoreDiskCacheEntry(sig: string, rawResponse: Buffer): void {
|
||||
this.privDiskCache.set(sig, rawResponse).then(() => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
||||
this.privDiskCache.set(sig, rawResponse).then((): void => {
|
||||
this.onEvent(new OCSPDiskCacheStoreEvent(sig));
|
||||
});
|
||||
}
|
||||
|
@ -311,16 +331,15 @@ export class CertCheckAgent {
|
|||
options.agent = agent;
|
||||
}
|
||||
|
||||
return new Promise<Buffer>((resolve: (value: Buffer) => void, reject: (error: string | Error) => void) => {
|
||||
ocsp.utils.getAuthorityInfo(req.cert, ocspMethod, (error: string, uri: string): void => {
|
||||
return new Promise<Buffer>((resolve: (value: Buffer) => void, reject: (error: string | Error) => void): void => {
|
||||
ocsp.utils.getAuthorityInfo(req.cert as tls.DetailedPeerCertificate, ocspMethod, (error: string, uri: string): void => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
|
||||
const parsedUri: {[k: string]: any} = parse.default(uri);
|
||||
parsedUri.path = parsedUri.pathname;
|
||||
options = { ...options, ...parsedUri };
|
||||
const url = new URL(uri);
|
||||
options = { ...options, host: url.host, protocol: url.protocol, port: url.port, path: url.pathname, hostname: url.host };
|
||||
|
||||
ocsp.utils.getResponse(options, req.data, (error: string, raw: Buffer): void => {
|
||||
if (error) {
|
||||
|
@ -328,14 +347,15 @@ export class CertCheckAgent {
|
|||
return;
|
||||
}
|
||||
|
||||
this.onEvent(new OCSPResponseRetrievedEvent(req.certID.toString("hex")));
|
||||
const certID: Buffer = req.certID as Buffer;
|
||||
this.onEvent(new OCSPResponseRetrievedEvent(certID.toString("hex")));
|
||||
resolve(raw);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private static onEvent = (event: OCSPEvent): void => {
|
||||
private static onEvent(event: OCSPEvent): void {
|
||||
Events.instance.onEvent(event);
|
||||
}
|
||||
|
||||
|
@ -355,8 +375,8 @@ export class CertCheckAgent {
|
|||
const httpProxyAgent: HttpsProxyAgent = CertCheckAgent.GetProxyAgent(this.privProxyInfo);
|
||||
const baseAgent: Agent.Agent = httpProxyAgent as unknown as Agent.Agent;
|
||||
|
||||
socketPromise = new Promise<net.Socket>((resolve: (value: net.Socket) => void, reject: (error: string | Error) => void) => {
|
||||
baseAgent.callback(request, options, (error: Error, socket: net.Socket) => {
|
||||
socketPromise = new Promise<net.Socket>((resolve: (value: net.Socket) => void, reject: (error: string | Error) => void): void => {
|
||||
baseAgent.callback(request, options, (error: Error, socket: net.Socket): void => {
|
||||
if (!!error) {
|
||||
reject(error);
|
||||
} else {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
|
@ -10,47 +11,49 @@ export class ConsoleLoggingListener implements IEventListener<PlatformEvent> {
|
|||
this.privLogLevelFilter = logLevelFilter;
|
||||
}
|
||||
|
||||
public onEvent = (event: PlatformEvent): void => {
|
||||
public onEvent(event: PlatformEvent): void {
|
||||
if (event.eventType >= this.privLogLevelFilter) {
|
||||
const log = this.toString(event);
|
||||
|
||||
switch (event.eventType) {
|
||||
case EventType.Debug:
|
||||
// tslint:disable-next-line:no-console
|
||||
// eslint-disable-next-line no-console
|
||||
console.debug(log);
|
||||
break;
|
||||
case EventType.Info:
|
||||
// tslint:disable-next-line:no-console
|
||||
// eslint-disable-next-line no-console
|
||||
console.info(log);
|
||||
break;
|
||||
case EventType.Warning:
|
||||
// tslint:disable-next-line:no-console
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(log);
|
||||
break;
|
||||
case EventType.Error:
|
||||
// tslint:disable-next-line:no-console
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(log);
|
||||
break;
|
||||
default:
|
||||
// tslint:disable-next-line:no-console
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(log);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private toString = (event: any): string => {
|
||||
private toString(event: PlatformEvent): string {
|
||||
const logFragments = [
|
||||
`${event.EventTime}`,
|
||||
`${event.Name}`,
|
||||
`${event.eventTime}`,
|
||||
`${event.name}`,
|
||||
];
|
||||
|
||||
for (const prop in event) {
|
||||
const e: any = event as any;
|
||||
for (const prop in e) {
|
||||
if (prop && event.hasOwnProperty(prop) &&
|
||||
prop !== "eventTime" && prop !== "eventType" &&
|
||||
prop !== "eventId" && prop !== "name" &&
|
||||
prop !== "constructor") {
|
||||
const value = event[prop];
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
const value = e[prop];
|
||||
let valueToLog = "<NULL>";
|
||||
if (value !== undefined && value !== null) {
|
||||
if (typeof (value) === "number" || typeof (value) === "string") {
|
||||
|
|
|
@ -67,7 +67,7 @@ export class FileAudioSource implements IAudioSource {
|
|||
return Promise.resolve(this.privSource);
|
||||
}
|
||||
|
||||
public turnOn = (): Promise<void> => {
|
||||
public turnOn(): Promise<void> {
|
||||
if (this.privFilename.lastIndexOf(".wav") !== this.privFilename.length - 4) {
|
||||
const errorMsg = this.privFilename + " is not supported. Only WAVE files are allowed at the moment.";
|
||||
this.onEvent(new AudioSourceErrorEvent(errorMsg, ""));
|
||||
|
@ -79,11 +79,11 @@ export class FileAudioSource implements IAudioSource {
|
|||
return;
|
||||
}
|
||||
|
||||
public id = (): string => {
|
||||
public id(): string {
|
||||
return this.privId;
|
||||
}
|
||||
|
||||
public attach = async (audioNodeId: string): Promise<IAudioStreamNode> => {
|
||||
public async attach(audioNodeId: string): Promise<IAudioStreamNode> {
|
||||
this.onEvent(new AudioStreamNodeAttachingEvent(this.privId, audioNodeId));
|
||||
|
||||
const stream: Stream<ArrayBuffer> = await this.upload(audioNodeId);
|
||||
|
@ -96,16 +96,12 @@ export class FileAudioSource implements IAudioSource {
|
|||
this.onEvent(new AudioStreamNodeDetachedEvent(this.privId, audioNodeId));
|
||||
await this.turnOff();
|
||||
},
|
||||
id: () => {
|
||||
return audioNodeId;
|
||||
},
|
||||
read: (): Promise<IStreamChunk<ArrayBuffer>> => {
|
||||
return stream.read();
|
||||
},
|
||||
id: (): string => audioNodeId,
|
||||
read: (): Promise<IStreamChunk<ArrayBuffer>> => stream.read(),
|
||||
});
|
||||
}
|
||||
|
||||
public detach = (audioNodeId: string): void => {
|
||||
public detach(audioNodeId: string): void {
|
||||
if (audioNodeId && this.privStreams[audioNodeId]) {
|
||||
this.privStreams[audioNodeId].close();
|
||||
delete this.privStreams[audioNodeId];
|
||||
|
@ -113,7 +109,7 @@ export class FileAudioSource implements IAudioSource {
|
|||
}
|
||||
}
|
||||
|
||||
public turnOff = (): Promise<void> => {
|
||||
public turnOff(): Promise<void> {
|
||||
for (const streamId in this.privStreams) {
|
||||
if (streamId) {
|
||||
const stream = this.privStreams[streamId];
|
||||
|
@ -132,8 +128,15 @@ export class FileAudioSource implements IAudioSource {
|
|||
}
|
||||
|
||||
public get deviceInfo(): Promise<ISpeechConfigAudioDevice> {
|
||||
return this.privAudioFormatPromise.then<ISpeechConfigAudioDevice>((result: AudioStreamFormatImpl) => {
|
||||
return Promise.resolve({
|
||||
return this.privAudioFormatPromise.then<ISpeechConfigAudioDevice>((result: AudioStreamFormatImpl): Promise<{
|
||||
bitspersample: number;
|
||||
channelcount: number;
|
||||
connectivity: connectivity.Unknown;
|
||||
manufacturer: string;
|
||||
model: string;
|
||||
samplerate: number;
|
||||
type: type.File;
|
||||
}> => ( Promise.resolve({
|
||||
bitspersample: result.bitsPerSample,
|
||||
channelcount: result.channels,
|
||||
connectivity: connectivity.Unknown,
|
||||
|
@ -141,8 +144,8 @@ export class FileAudioSource implements IAudioSource {
|
|||
model: "File",
|
||||
samplerate: result.samplesPerSec,
|
||||
type: type.File,
|
||||
});
|
||||
});
|
||||
})
|
||||
));
|
||||
}
|
||||
|
||||
private readHeader(): Promise<AudioStreamFormatImpl> {
|
||||
|
@ -155,9 +158,7 @@ export class FileAudioSource implements IAudioSource {
|
|||
const processHeader = (header: ArrayBuffer): void => {
|
||||
const view: DataView = new DataView(header);
|
||||
|
||||
const getWord = (index: number): string => {
|
||||
return String.fromCharCode(view.getUint8(index), view.getUint8(index + 1), view.getUint8(index + 2), view.getUint8(index + 3));
|
||||
};
|
||||
const getWord = (index: number): string => String.fromCharCode(view.getUint8(index), view.getUint8(index + 1), view.getUint8(index + 2), view.getUint8(index + 3));
|
||||
|
||||
// RIFF 4 bytes.
|
||||
if ("RIFF" !== getWord(0)) {
|
||||
|
@ -191,7 +192,7 @@ export class FileAudioSource implements IAudioSource {
|
|||
if (typeof window !== "undefined" && typeof Blob !== "undefined" && header instanceof Blob) {
|
||||
const reader: FileReader = new FileReader();
|
||||
|
||||
reader.onload = (event: Event) => {
|
||||
reader.onload = (event: Event): void => {
|
||||
const header: ArrayBuffer = (event.target as FileReader).result as ArrayBuffer;
|
||||
processHeader(header);
|
||||
};
|
||||
|
@ -205,7 +206,7 @@ export class FileAudioSource implements IAudioSource {
|
|||
}
|
||||
|
||||
private async upload(audioNodeId: string): Promise<Stream<ArrayBuffer>> {
|
||||
const onerror = (error: string) => {
|
||||
const onerror = (error: string): void => {
|
||||
const errorMsg = `Error occurred while processing '${this.privFilename}'. ${error}`;
|
||||
this.onEvent(new AudioStreamNodeErrorEvent(this.privId, audioNodeId, errorMsg));
|
||||
throw new Error(errorMsg);
|
||||
|
@ -235,9 +236,9 @@ export class FileAudioSource implements IAudioSource {
|
|||
|
||||
if (typeof window !== "undefined" && typeof Blob !== "undefined" && chunk instanceof Blob) {
|
||||
const reader: FileReader = new FileReader();
|
||||
reader.onerror = (ev: ProgressEvent<FileReader>) => { onerror(ev.toString()); };
|
||||
reader.onerror = (ev: ProgressEvent<FileReader>): void => onerror(ev.toString());
|
||||
|
||||
reader.onload = (event: Event) => {
|
||||
reader.onload = (event: Event): void => {
|
||||
const fileBuffer: ArrayBuffer = (event.target as FileReader).result as ArrayBuffer;
|
||||
processFile(fileBuffer);
|
||||
};
|
||||
|
@ -250,11 +251,11 @@ export class FileAudioSource implements IAudioSource {
|
|||
|
||||
return stream;
|
||||
} catch (e) {
|
||||
onerror(e);
|
||||
onerror(e as string);
|
||||
}
|
||||
}
|
||||
|
||||
private onEvent = (event: AudioSourceEvent): void => {
|
||||
private onEvent(event: AudioSourceEvent): void {
|
||||
this.privEvents.onEvent(event);
|
||||
Events.instance.onEvent(event);
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import {
|
|||
IStringDictionary,
|
||||
Stream,
|
||||
} from "../common/Exports";
|
||||
import { IStreamChunk } from "../common/Stream";
|
||||
import {
|
||||
AudioStreamFormat,
|
||||
AudioStreamFormatImpl,
|
||||
|
@ -34,8 +35,8 @@ import { IRecorder } from "./IRecorder";
|
|||
|
||||
// Extending the default definition with browser specific definitions for backward compatibility
|
||||
interface INavigator extends Navigator {
|
||||
webkitGetUserMedia?: (constraints: MediaStreamConstraints, successCallback: NavigatorUserMediaSuccessCallback, errorCallback: NavigatorUserMediaErrorCallback) => void;
|
||||
mozGetUserMedia?: (constraints: MediaStreamConstraints, successCallback: NavigatorUserMediaSuccessCallback, errorCallback: NavigatorUserMediaErrorCallback) => void;
|
||||
webkitGetUserMedia?: (constraints: MediaStreamConstraints, successCallback: NavigatorUserMediaSuccessCallback | undefined, errorCallback: NavigatorUserMediaErrorCallback) => void;
|
||||
mozGetUserMedia?: (constraints: MediaStreamConstraints, successCallback: NavigatorUserMediaSuccessCallback | undefined, errorCallback: NavigatorUserMediaErrorCallback) => void;
|
||||
msGetUserMedia?: (constraints: MediaStreamConstraints, successCallback: NavigatorUserMediaSuccessCallback, errorCallback: NavigatorUserMediaErrorCallback) => void;
|
||||
}
|
||||
|
||||
|
@ -85,7 +86,7 @@ export class MicAudioSource implements IAudioSource {
|
|||
return Promise.reject("Not implemented for Mic input");
|
||||
}
|
||||
|
||||
public turnOn = (): Promise<void> => {
|
||||
public turnOn(): Promise<void> {
|
||||
if (this.privInitializeDeferral) {
|
||||
return this.privInitializeDeferral.promise;
|
||||
}
|
||||
|
@ -96,10 +97,10 @@ export class MicAudioSource implements IAudioSource {
|
|||
this.createAudioContext();
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
const typedError: Error = error as Error;
|
||||
const typedError: Error = error;
|
||||
this.privInitializeDeferral.reject(typedError.name + ": " + typedError.message);
|
||||
} else {
|
||||
this.privInitializeDeferral.reject(error);
|
||||
this.privInitializeDeferral.reject(error as string);
|
||||
}
|
||||
return this.privInitializeDeferral.promise;
|
||||
}
|
||||
|
@ -107,6 +108,7 @@ export class MicAudioSource implements IAudioSource {
|
|||
const nav = window.navigator as INavigator;
|
||||
|
||||
let getUserMedia = (
|
||||
// eslint-disable-next-line
|
||||
nav.getUserMedia ||
|
||||
nav.webkitGetUserMedia ||
|
||||
nav.mozGetUserMedia ||
|
||||
|
@ -127,7 +129,7 @@ export class MicAudioSource implements IAudioSource {
|
|||
this.privInitializeDeferral.reject(errorMsg);
|
||||
this.onEvent(new AudioSourceErrorEvent(errorMsg, "")); // mic initialized error - no streamid at this point
|
||||
} else {
|
||||
const next = () => {
|
||||
const next = (): void => {
|
||||
this.onEvent(new AudioSourceInitializingEvent(this.privId)); // no stream id
|
||||
if (this.privMediaStream && this.privMediaStream.active) {
|
||||
this.onEvent(new AudioSourceReadyEvent(this.privId));
|
||||
|
@ -135,12 +137,12 @@ export class MicAudioSource implements IAudioSource {
|
|||
} else {
|
||||
getUserMedia(
|
||||
{ audio: this.deviceId ? { deviceId: this.deviceId } : true, video: false },
|
||||
(mediaStream: MediaStream) => {
|
||||
(mediaStream: MediaStream): void => {
|
||||
this.privMediaStream = mediaStream;
|
||||
this.onEvent(new AudioSourceReadyEvent(this.privId));
|
||||
this.privInitializeDeferral.resolve();
|
||||
}, (error: MediaStreamError) => {
|
||||
const errorMsg = `Error occurred during microphone initialization: ${error}`;
|
||||
}, (error: any): void => {
|
||||
const errorMsg = `Error occurred during microphone initialization: ${error as string}`;
|
||||
this.privInitializeDeferral.reject(errorMsg);
|
||||
this.onEvent(new AudioSourceErrorEvent(this.privId, errorMsg));
|
||||
});
|
||||
|
@ -152,8 +154,8 @@ export class MicAudioSource implements IAudioSource {
|
|||
// https://github.com/WebAudio/web-audio-api/issues/790
|
||||
this.privContext.resume()
|
||||
.then(next)
|
||||
.catch((reason: any) => {
|
||||
this.privInitializeDeferral.reject(`Failed to initialize audio context: ${reason}`);
|
||||
.catch((reason: any): void => {
|
||||
this.privInitializeDeferral.reject(`Failed to initialize audio context: ${reason as string}`);
|
||||
});
|
||||
} else {
|
||||
next();
|
||||
|
@ -163,34 +165,30 @@ export class MicAudioSource implements IAudioSource {
|
|||
return this.privInitializeDeferral.promise;
|
||||
}
|
||||
|
||||
public id = (): string => {
|
||||
public id(): string {
|
||||
return this.privId;
|
||||
}
|
||||
|
||||
public attach = (audioNodeId: string): Promise<IAudioStreamNode> => {
|
||||
public attach(audioNodeId: string): Promise<IAudioStreamNode> {
|
||||
this.onEvent(new AudioStreamNodeAttachingEvent(this.privId, audioNodeId));
|
||||
|
||||
return this.listen(audioNodeId).then<IAudioStreamNode>(
|
||||
(stream: Stream<ArrayBuffer>) => {
|
||||
(stream: Stream<ArrayBuffer>): IAudioStreamNode => {
|
||||
this.onEvent(new AudioStreamNodeAttachedEvent(this.privId, audioNodeId));
|
||||
return {
|
||||
detach: async () => {
|
||||
detach: async (): Promise<void> => {
|
||||
stream.readEnded();
|
||||
delete this.privStreams[audioNodeId];
|
||||
this.onEvent(new AudioStreamNodeDetachedEvent(this.privId, audioNodeId));
|
||||
return this.turnOff();
|
||||
},
|
||||
id: () => {
|
||||
return audioNodeId;
|
||||
},
|
||||
read: () => {
|
||||
return stream.read();
|
||||
},
|
||||
id: (): string => audioNodeId,
|
||||
read: (): Promise<IStreamChunk<ArrayBuffer>> => stream.read(),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
public detach = (audioNodeId: string): void => {
|
||||
public detach(audioNodeId: string): void {
|
||||
if (audioNodeId && this.privStreams[audioNodeId]) {
|
||||
this.privStreams[audioNodeId].close();
|
||||
delete this.privStreams[audioNodeId];
|
||||
|
@ -211,6 +209,7 @@ export class MicAudioSource implements IAudioSource {
|
|||
this.onEvent(new AudioSourceOffEvent(this.privId)); // no stream now
|
||||
if (this.privInitializeDeferral) {
|
||||
// Correctly handle when browser forces mic off before turnOn() completes
|
||||
// eslint-disable-next-line @typescript-eslint/await-thenable
|
||||
await this.privInitializeDeferral;
|
||||
this.privInitializeDeferral = null;
|
||||
}
|
||||
|
@ -225,8 +224,8 @@ export class MicAudioSource implements IAudioSource {
|
|||
}
|
||||
|
||||
public get deviceInfo(): Promise<ISpeechConfigAudioDevice> {
|
||||
return this.getMicrophoneLabel().then((label: string) => {
|
||||
return {
|
||||
return this.getMicrophoneLabel().then((label: string): ISpeechConfigAudioDevice => (
|
||||
{
|
||||
bitspersample: MicAudioSource.AUDIOFORMAT.bitsPerSample,
|
||||
channelcount: MicAudioSource.AUDIOFORMAT.channels,
|
||||
connectivity: connectivity.Unknown,
|
||||
|
@ -234,8 +233,8 @@ export class MicAudioSource implements IAudioSource {
|
|||
model: label,
|
||||
samplerate: MicAudioSource.AUDIOFORMAT.samplesPerSec,
|
||||
type: type.Microphones,
|
||||
};
|
||||
});
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
public setProperty(name: string, value: string): void {
|
||||
|
@ -273,7 +272,7 @@ export class MicAudioSource implements IAudioSource {
|
|||
const deferred: Deferred<string> = new Deferred<string>();
|
||||
|
||||
// Enumerate the media devices.
|
||||
navigator.mediaDevices.enumerateDevices().then((devices: MediaDeviceInfo[]) => {
|
||||
navigator.mediaDevices.enumerateDevices().then((devices: MediaDeviceInfo[]): void => {
|
||||
for (const device of devices) {
|
||||
if (device.deviceId === microphoneDeviceId) {
|
||||
// Found the device
|
||||
|
@ -282,31 +281,31 @@ export class MicAudioSource implements IAudioSource {
|
|||
}
|
||||
}
|
||||
deferred.resolve(this.privMicrophoneLabel);
|
||||
}, () => deferred.resolve(this.privMicrophoneLabel));
|
||||
}, (): Deferred<string> => deferred.resolve(this.privMicrophoneLabel));
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
private listen = async (audioNodeId: string): Promise<Stream<ArrayBuffer>> => {
|
||||
private async listen(audioNodeId: string): Promise<Stream<ArrayBuffer>> {
|
||||
await this.turnOn();
|
||||
const stream = new ChunkedArrayBufferStream(this.privOutputChunkSize, audioNodeId);
|
||||
this.privStreams[audioNodeId] = stream;
|
||||
try {
|
||||
this.privRecorder.record(this.privContext, this.privMediaStream, stream);
|
||||
} catch (error) {
|
||||
this.onEvent(new AudioStreamNodeErrorEvent(this.privId, audioNodeId, error));
|
||||
this.onEvent(new AudioStreamNodeErrorEvent(this.privId, audioNodeId, error as string));
|
||||
throw error;
|
||||
}
|
||||
const result: Stream<ArrayBuffer> = stream;
|
||||
return result;
|
||||
}
|
||||
|
||||
private onEvent = (event: AudioSourceEvent): void => {
|
||||
private onEvent(event: AudioSourceEvent): void {
|
||||
this.privEvents.onEvent(event);
|
||||
Events.instance.onEvent(event);
|
||||
}
|
||||
|
||||
private createAudioContext = (): void => {
|
||||
private createAudioContext(): void {
|
||||
if (!!this.privContext) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -13,11 +13,10 @@ export class PcmRecorder implements IRecorder {
|
|||
this.privStopInputOnRelease = stopInputOnRelease;
|
||||
}
|
||||
|
||||
public record = (context: AudioContext, mediaStream: MediaStream, outputStream: Stream<ArrayBuffer>): void => {
|
||||
public record(context: AudioContext, mediaStream: MediaStream, outputStream: Stream<ArrayBuffer>): void {
|
||||
const desiredSampleRate = 16000;
|
||||
|
||||
const waveStreamEncoder = new RiffPcmEncoder(context.sampleRate, desiredSampleRate);
|
||||
let needHeader: boolean = true;
|
||||
|
||||
const micInput = context.createMediaStreamSource(mediaStream);
|
||||
if (!this.privSpeechProcessorScript) {
|
||||
|
@ -35,12 +34,13 @@ export class PcmRecorder implements IRecorder {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
registerProcessor('speech-processor', SP);`; // tslint:disable-line:max-line-length
|
||||
registerProcessor('speech-processor', SP);`;
|
||||
const blob = new Blob([workletScript], { type: "application/javascript; charset=utf-8" });
|
||||
this.privSpeechProcessorScript = URL.createObjectURL(blob);
|
||||
}
|
||||
|
||||
const attachScriptProcessor = () => {
|
||||
const attachScriptProcessor = (): void => {
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
||||
const scriptNode = (() => {
|
||||
let bufferSize = 0;
|
||||
try {
|
||||
|
@ -56,7 +56,7 @@ export class PcmRecorder implements IRecorder {
|
|||
return context.createScriptProcessor(bufferSize, 1, 1);
|
||||
}
|
||||
})();
|
||||
scriptNode.onaudioprocess = (event: AudioProcessingEvent) => {
|
||||
scriptNode.onaudioprocess = (event: AudioProcessingEvent): void => {
|
||||
const inputFrame = event.inputBuffer.getChannelData(0);
|
||||
|
||||
if (outputStream && !outputStream.isClosed) {
|
||||
|
@ -67,7 +67,6 @@ export class PcmRecorder implements IRecorder {
|
|||
isEnd: false,
|
||||
timeReceived: Date.now(),
|
||||
});
|
||||
needHeader = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -86,9 +85,9 @@ export class PcmRecorder implements IRecorder {
|
|||
if (!!this.privSpeechProcessorScript && !!context.audioWorklet) {
|
||||
context.audioWorklet
|
||||
.addModule(this.privSpeechProcessorScript)
|
||||
.then(() => {
|
||||
.then((): void => {
|
||||
const workletNode = new AudioWorkletNode(context, "speech-processor");
|
||||
workletNode.port.onmessage = (ev: MessageEvent) => {
|
||||
workletNode.port.onmessage = (ev: MessageEvent): void => {
|
||||
const inputFrame: Float32Array = ev.data as Float32Array;
|
||||
|
||||
if (outputStream && !outputStream.isClosed) {
|
||||
|
@ -99,7 +98,6 @@ export class PcmRecorder implements IRecorder {
|
|||
isEnd: false,
|
||||
timeReceived: Date.now(),
|
||||
});
|
||||
needHeader = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -111,19 +109,19 @@ export class PcmRecorder implements IRecorder {
|
|||
stream: mediaStream,
|
||||
};
|
||||
})
|
||||
.catch(() => {
|
||||
.catch((): void => {
|
||||
attachScriptProcessor();
|
||||
});
|
||||
} else {
|
||||
try {
|
||||
attachScriptProcessor();
|
||||
} catch (err) {
|
||||
throw new Error(`Unable to start audio worklet node for PCMRecorder: ${err}`);
|
||||
throw new Error(`Unable to start audio worklet node for PCMRecorder: ${err as string}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public releaseMediaResources = (context: AudioContext): void => {
|
||||
public releaseMediaResources(context: AudioContext): void {
|
||||
if (this.privMediaResources) {
|
||||
if (this.privMediaResources.scriptProcessorNode) {
|
||||
this.privMediaResources.scriptProcessorNode.disconnect(context.destination);
|
||||
|
@ -132,7 +130,7 @@ export class PcmRecorder implements IRecorder {
|
|||
if (this.privMediaResources.source) {
|
||||
this.privMediaResources.source.disconnect();
|
||||
if (this.privStopInputOnRelease) {
|
||||
this.privMediaResources.stream.getTracks().forEach((track: any) => track.stop());
|
||||
this.privMediaResources.stream.getTracks().forEach((track: MediaStreamTrack): void => track.stop());
|
||||
}
|
||||
this.privMediaResources.source = null;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import { AudioStreamFormatImpl } from "../../src/sdk/Audio/AudioStreamFormat";
|
||||
// eslint-disable-next-line max-classes-per-file
|
||||
import {
|
||||
IAudioStreamNode,
|
||||
IStreamChunk,
|
||||
|
@ -24,7 +24,7 @@ export class ReplayableAudioNode implements IAudioStreamNode {
|
|||
this.privBytesPerSecond = bytesPerSecond;
|
||||
}
|
||||
|
||||
public id = (): string => {
|
||||
public id(): string {
|
||||
return this.privAudioNode.id();
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@ export class ReplayableAudioNode implements IAudioStreamNode {
|
|||
}
|
||||
|
||||
return this.privAudioNode.read()
|
||||
.then((result: IStreamChunk<ArrayBuffer>) => {
|
||||
.then((result: IStreamChunk<ArrayBuffer>): IStreamChunk<ArrayBuffer> => {
|
||||
if (result && result.buffer) {
|
||||
this.privBuffers.push(new BufferEntry(result, this.privBufferSerial++, this.privBufferedBytes));
|
||||
this.privBufferedBytes += result.buffer.byteLength;
|
||||
|
@ -139,7 +139,6 @@ export class ReplayableAudioNode implements IAudioStreamNode {
|
|||
// Primary use of this class is to help debugging problems with the replay
|
||||
// code. If the memory cost of alloc / dealloc gets too much, drop it and just use
|
||||
// the ArrayBuffer directly.
|
||||
// tslint:disable-next-line:max-classes-per-file
|
||||
class BufferEntry {
|
||||
public chunk: IStreamChunk<ArrayBuffer>;
|
||||
public serial: number;
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import bent, { BentResponse } from "bent";
|
||||
import {
|
||||
ArgumentNullError,
|
||||
Deferred
|
||||
} from "../common/Exports";
|
||||
import { IRequestOptions } from "./Exports";
|
||||
|
||||
import bent, { BentResponse } from "bent";
|
||||
|
||||
export enum RestRequestType {
|
||||
Get = "GET",
|
||||
Post = "POST",
|
||||
|
@ -25,11 +24,17 @@ export interface IRestResponse {
|
|||
headers: string;
|
||||
}
|
||||
|
||||
interface JsonError {
|
||||
error?: {
|
||||
message: string;
|
||||
};
|
||||
}
|
||||
|
||||
// accept rest operations via request method and return abstracted objects from server response
|
||||
export class RestMessageAdapter {
|
||||
|
||||
private privIgnoreCache: boolean;
|
||||
private privHeaders: { [key: string]: string; };
|
||||
private privHeaders: { [key: string]: string };
|
||||
|
||||
public constructor(
|
||||
configParams: IRequestOptions
|
||||
|
@ -48,8 +53,8 @@ export class RestMessageAdapter {
|
|||
|
||||
try {
|
||||
const arr = headers.trim().split(/[\r\n]+/);
|
||||
const headerMap: any = {};
|
||||
arr.forEach((line: any) => {
|
||||
const headerMap: { [key: string]: string } = {};
|
||||
arr.forEach((line: string): void => {
|
||||
const parts = line.split(": ");
|
||||
const header = parts.shift().toLowerCase();
|
||||
const value = parts.join(": ");
|
||||
|
@ -76,16 +81,16 @@ export class RestMessageAdapter {
|
|||
public request(
|
||||
method: RestRequestType,
|
||||
uri: string,
|
||||
queryParams: any = {},
|
||||
body: any = null,
|
||||
queryParams: { [key: string]: any } = {},
|
||||
body: bent.RequestBody = null,
|
||||
binaryBody: Blob | Buffer = null,
|
||||
): Promise<IRestResponse> {
|
||||
|
||||
const responseReceivedDeferral = new Deferred<IRestResponse>();
|
||||
|
||||
const requestCommand = method === RestRequestType.File ? "POST" : method;
|
||||
const handleRestResponse = (data: BentResponse, j: any = {}): IRestResponse => {
|
||||
const d: { statusText?: string, statusMessage?: string } = data;
|
||||
const handleRestResponse = (data: BentResponse, j: JsonError = {}): IRestResponse => {
|
||||
const d: { statusText?: string; statusMessage?: string } = data;
|
||||
return {
|
||||
data: JSON.stringify(j),
|
||||
headers: JSON.stringify(data.headers),
|
||||
|
@ -96,32 +101,32 @@ export class RestMessageAdapter {
|
|||
};
|
||||
};
|
||||
|
||||
const blobToArrayBuffer = (blob: Blob) => {
|
||||
const blobToArrayBuffer = (blob: Blob): Promise<unknown> => {
|
||||
const reader = new FileReader();
|
||||
reader.readAsArrayBuffer(blob);
|
||||
return new Promise((resolve: (value: unknown) => void) => {
|
||||
reader.onloadend = () => {
|
||||
return new Promise((resolve: (value: unknown) => void): void => {
|
||||
reader.onloadend = (): void => {
|
||||
resolve(reader.result);
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
const send = (postData: any): void => {
|
||||
const send = (postData: bent.RequestBody): void => {
|
||||
const sendRequest = bent(uri, requestCommand, this.privHeaders, 200, 201, 202, 204, 400, 401, 402, 403, 404);
|
||||
const params = this.queryParams(queryParams) === "" ? "" : "?" + this.queryParams(queryParams);
|
||||
sendRequest(params, postData).then( async (data: any) => {
|
||||
const params = this.queryParams(queryParams) === "" ? "" : `?${this.queryParams(queryParams)}`;
|
||||
sendRequest(params, postData).then( async (data: BentResponse): Promise<void> => {
|
||||
if (method === RestRequestType.Delete || data.statusCode === 204) {
|
||||
// No JSON from Delete and reset (204) operations
|
||||
responseReceivedDeferral.resolve(handleRestResponse(data));
|
||||
} else {
|
||||
try {
|
||||
const j: any = await data.json();
|
||||
const j: JsonError = await data.json() as JsonError;
|
||||
responseReceivedDeferral.resolve(handleRestResponse(data, j));
|
||||
} catch {
|
||||
responseReceivedDeferral.resolve(handleRestResponse(data));
|
||||
}
|
||||
}
|
||||
}).catch((error: string) => {
|
||||
}).catch((error: string): void => {
|
||||
responseReceivedDeferral.reject(error);
|
||||
});
|
||||
};
|
||||
|
@ -135,10 +140,10 @@ export class RestMessageAdapter {
|
|||
this.privHeaders["content-type"] = contentType;
|
||||
this.privHeaders["Content-Type"] = contentType;
|
||||
if (typeof (Blob) !== "undefined" && binaryBody instanceof Blob) {
|
||||
blobToArrayBuffer(binaryBody as Blob).then( (res: any) => {
|
||||
blobToArrayBuffer(binaryBody).then( (res: bent.RequestBody): void => {
|
||||
send(res);
|
||||
}).catch((error: any) => {
|
||||
responseReceivedDeferral.reject(error);
|
||||
}).catch((error: any): void => {
|
||||
responseReceivedDeferral.reject(error as string);
|
||||
});
|
||||
} else {
|
||||
send(binaryBody as Buffer);
|
||||
|
@ -153,14 +158,14 @@ export class RestMessageAdapter {
|
|||
return responseReceivedDeferral.promise;
|
||||
}
|
||||
|
||||
private withQuery(url: string, params: any = {}): any {
|
||||
private withQuery(url: string, params: { [key: string]: string } = {}): any {
|
||||
const queryString = this.queryParams(params);
|
||||
return queryString ? url + (url.indexOf("?") === -1 ? "?" : "&") + queryString : url;
|
||||
}
|
||||
|
||||
private queryParams(params: any = {}): any {
|
||||
private queryParams(params: { [key: string]: string } = {}): string {
|
||||
return Object.keys(params)
|
||||
.map((k: any) => encodeURIComponent(k) + "=" + encodeURIComponent(params[k]))
|
||||
.map((k: string): string => encodeURIComponent(k) + "=" + encodeURIComponent(params[k]))
|
||||
.join("&");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@ export class WebsocketConnection implements IConnection {
|
|||
}
|
||||
}
|
||||
|
||||
public isDisposed = (): boolean => {
|
||||
public isDisposed(): boolean {
|
||||
return this.privIsDisposed;
|
||||
}
|
||||
|
||||
|
@ -96,19 +96,19 @@ export class WebsocketConnection implements IConnection {
|
|||
return this.privId;
|
||||
}
|
||||
|
||||
public state = (): ConnectionState => {
|
||||
public state(): ConnectionState {
|
||||
return this.privConnectionMessageAdapter.state;
|
||||
}
|
||||
|
||||
public open = (): Promise<ConnectionOpenResponse> => {
|
||||
public open(): Promise<ConnectionOpenResponse> {
|
||||
return this.privConnectionMessageAdapter.open();
|
||||
}
|
||||
|
||||
public send = (message: ConnectionMessage): Promise<void> => {
|
||||
public send(message: ConnectionMessage): Promise<void> {
|
||||
return this.privConnectionMessageAdapter.send(message);
|
||||
}
|
||||
|
||||
public read = (): Promise<ConnectionMessage> => {
|
||||
public read(): Promise<ConnectionMessage> {
|
||||
return this.privConnectionMessageAdapter.read();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// Node.JS specific web socket / browser support.
|
||||
import ws from "ws";
|
||||
import { HeaderNames } from "../common.speech/HeaderNames";
|
||||
import {
|
||||
ArgumentNullError,
|
||||
|
@ -25,8 +27,6 @@ import {
|
|||
} from "../common/Exports";
|
||||
import { ProxyInfo } from "./ProxyInfo";
|
||||
|
||||
// Node.JS specific web socket / browser support.
|
||||
import ws from "ws";
|
||||
import { CertCheckAgent } from "./CertChecks";
|
||||
|
||||
interface ISendItem {
|
||||
|
@ -49,7 +49,7 @@ export class WebsocketMessageAdapter {
|
|||
private privConnectionId: string;
|
||||
private privUri: string;
|
||||
private proxyInfo: ProxyInfo;
|
||||
private privHeaders: { [key: string]: string; };
|
||||
private privHeaders: { [key: string]: string };
|
||||
private privLastErrorReceived: string;
|
||||
private privEnableCompression: boolean;
|
||||
|
||||
|
@ -60,7 +60,7 @@ export class WebsocketMessageAdapter {
|
|||
connectionId: string,
|
||||
messageFormatter: IWebsocketMessageFormatter,
|
||||
proxyInfo: ProxyInfo,
|
||||
headers: { [key: string]: string; },
|
||||
headers: { [key: string]: string },
|
||||
enableCompression: boolean) {
|
||||
|
||||
if (!uri) {
|
||||
|
@ -90,7 +90,7 @@ export class WebsocketMessageAdapter {
|
|||
return this.privConnectionState;
|
||||
}
|
||||
|
||||
public open = (): Promise<ConnectionOpenResponse> => {
|
||||
public open(): Promise<ConnectionOpenResponse> {
|
||||
if (this.privConnectionState === ConnectionState.Disconnected) {
|
||||
return Promise.reject<ConnectionOpenResponse>(`Cannot open a connection that is in ${this.privConnectionState} state`);
|
||||
}
|
||||
|
@ -129,6 +129,7 @@ export class WebsocketMessageAdapter {
|
|||
} else if (protocol?.toLocaleLowerCase() === "ws:") {
|
||||
protocol = "http:";
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
(options.agent as any).protocol = protocol;
|
||||
this.privWebsocketClient = new ws(this.privUri, options);
|
||||
}
|
||||
|
@ -141,13 +142,13 @@ export class WebsocketMessageAdapter {
|
|||
Events.instance.onEvent(new BackgroundEvent(reason));
|
||||
});
|
||||
} catch (error) {
|
||||
this.privConnectionEstablishDeferral.resolve(new ConnectionOpenResponse(500, error));
|
||||
this.privConnectionEstablishDeferral.resolve(new ConnectionOpenResponse(500, error as string));
|
||||
return this.privConnectionEstablishDeferral.promise;
|
||||
}
|
||||
|
||||
this.onEvent(new ConnectionStartEvent(this.privConnectionId, this.privUri));
|
||||
|
||||
this.privWebsocketClient.onopen = (e: { target: WebSocket | ws }) => {
|
||||
this.privWebsocketClient.onopen = (): void => {
|
||||
this.privCertificateValidatedDeferral.promise.then((): void => {
|
||||
this.privConnectionState = ConnectionState.Connected;
|
||||
this.onEvent(new ConnectionEstablishedEvent(this.privConnectionId));
|
||||
|
@ -157,12 +158,12 @@ export class WebsocketMessageAdapter {
|
|||
});
|
||||
};
|
||||
|
||||
this.privWebsocketClient.onerror = (e: { error: any; message: string; type: string; target: WebSocket | ws }) => {
|
||||
this.privWebsocketClient.onerror = (e: { error: any; message: string; type: string; target: WebSocket | ws }): void => {
|
||||
this.onEvent(new ConnectionErrorEvent(this.privConnectionId, e.message, e.type));
|
||||
this.privLastErrorReceived = e.message;
|
||||
};
|
||||
|
||||
this.privWebsocketClient.onclose = (e: { wasClean: boolean; code: number; reason: string; target: WebSocket | ws }) => {
|
||||
this.privWebsocketClient.onclose = (e: { wasClean: boolean; code: number; reason: string; target: WebSocket | ws }): void => {
|
||||
if (this.privConnectionState === ConnectionState.Connecting) {
|
||||
this.privConnectionState = ConnectionState.Disconnected;
|
||||
// this.onEvent(new ConnectionEstablishErrorEvent(this.connectionId, e.code, e.reason));
|
||||
|
@ -178,7 +179,7 @@ export class WebsocketMessageAdapter {
|
|||
});
|
||||
};
|
||||
|
||||
this.privWebsocketClient.onmessage = (e: { data: ws.Data; type: string; target: WebSocket | ws }) => {
|
||||
this.privWebsocketClient.onmessage = (e: { data: ws.Data; type: string; target: WebSocket | ws }): void => {
|
||||
const networkReceivedTime = new Date().toISOString();
|
||||
if (this.privConnectionState === ConnectionState.Connected) {
|
||||
const deferred = new Deferred<ConnectionMessage>();
|
||||
|
@ -188,10 +189,10 @@ export class WebsocketMessageAdapter {
|
|||
const rawMessage = new RawWebsocketMessage(MessageType.Binary, e.data);
|
||||
this.privMessageFormatter
|
||||
.toConnectionMessage(rawMessage)
|
||||
.then((connectionMessage: ConnectionMessage) => {
|
||||
.then((connectionMessage: ConnectionMessage): void => {
|
||||
this.onEvent(new ConnectionMessageReceivedEvent(this.privConnectionId, networkReceivedTime, connectionMessage));
|
||||
deferred.resolve(connectionMessage);
|
||||
}, (error: string) => {
|
||||
}, (error: string): void => {
|
||||
// TODO: Events for these ?
|
||||
deferred.reject(`Invalid binary message format. Error: ${error}`);
|
||||
});
|
||||
|
@ -199,10 +200,10 @@ export class WebsocketMessageAdapter {
|
|||
const rawMessage = new RawWebsocketMessage(MessageType.Text, e.data);
|
||||
this.privMessageFormatter
|
||||
.toConnectionMessage(rawMessage)
|
||||
.then((connectionMessage: ConnectionMessage) => {
|
||||
.then((connectionMessage: ConnectionMessage): void => {
|
||||
this.onEvent(new ConnectionMessageReceivedEvent(this.privConnectionId, networkReceivedTime, connectionMessage));
|
||||
deferred.resolve(connectionMessage);
|
||||
}, (error: string) => {
|
||||
}, (error: string): void => {
|
||||
// TODO: Events for these ?
|
||||
deferred.reject(`Invalid text message format. Error: ${error}`);
|
||||
});
|
||||
|
@ -213,7 +214,7 @@ export class WebsocketMessageAdapter {
|
|||
return this.privConnectionEstablishDeferral.promise;
|
||||
}
|
||||
|
||||
public send = (message: ConnectionMessage): Promise<void> => {
|
||||
public send(message: ConnectionMessage): Promise<void> {
|
||||
if (this.privConnectionState !== ConnectionState.Connected) {
|
||||
return Promise.reject(`Cannot send on connection that is in ${ConnectionState[this.privConnectionState]} state`);
|
||||
}
|
||||
|
@ -225,20 +226,20 @@ export class WebsocketMessageAdapter {
|
|||
|
||||
this.privMessageFormatter
|
||||
.fromConnectionMessage(message)
|
||||
.then((rawMessage: RawWebsocketMessage) => {
|
||||
.then((rawMessage: RawWebsocketMessage): void => {
|
||||
messageSendDeferral.resolve({
|
||||
Message: message,
|
||||
RawWebsocketMessage: rawMessage,
|
||||
sendStatusDeferral: messageSendStatusDeferral,
|
||||
});
|
||||
}, (error: string) => {
|
||||
}, (error: string): void => {
|
||||
messageSendDeferral.reject(`Error formatting the message. ${error}`);
|
||||
});
|
||||
|
||||
return messageSendStatusDeferral.promise;
|
||||
}
|
||||
|
||||
public read = (): Promise<ConnectionMessage> => {
|
||||
public read(): Promise<ConnectionMessage> {
|
||||
if (this.privConnectionState !== ConnectionState.Connected) {
|
||||
return Promise.reject<ConnectionMessage>(`Cannot read on connection that is in ${this.privConnectionState} state`);
|
||||
}
|
||||
|
@ -246,7 +247,7 @@ export class WebsocketMessageAdapter {
|
|||
return this.privReceivingMessageQueue.dequeue();
|
||||
}
|
||||
|
||||
public close = (reason?: string): Promise<void> => {
|
||||
public close(reason?: string): Promise<void> {
|
||||
if (this.privWebsocketClient) {
|
||||
if (this.privConnectionState !== ConnectionState.Disconnected) {
|
||||
this.privWebsocketClient.close(1000, reason ? reason : "Normal closure by client");
|
||||
|
@ -262,7 +263,7 @@ export class WebsocketMessageAdapter {
|
|||
return this.privConnectionEvents;
|
||||
}
|
||||
|
||||
private sendRawMessage = (sendItem: ISendItem): Promise<void> => {
|
||||
private sendRawMessage(sendItem: ISendItem): Promise<void> {
|
||||
try {
|
||||
// indicates we are draining the queue and it came with no message;
|
||||
if (!sendItem) {
|
||||
|
@ -273,6 +274,7 @@ export class WebsocketMessageAdapter {
|
|||
|
||||
// add a check for the ws readystate in order to stop the red console error 'WebSocket is already in CLOSING or CLOSED state' appearing
|
||||
if (this.isWebsocketOpen) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||
this.privWebsocketClient.send(sendItem.RawWebsocketMessage.payload);
|
||||
} else {
|
||||
return Promise.reject("websocket send error: Websocket not ready " + this.privConnectionId + " " + sendItem.Message.id + " " + new Error().stack);
|
||||
|
@ -280,7 +282,7 @@ export class WebsocketMessageAdapter {
|
|||
return Promise.resolve();
|
||||
|
||||
} catch (e) {
|
||||
return Promise.reject(`websocket send error: ${e}`);
|
||||
return Promise.reject(`websocket send error: ${e as string}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -288,12 +290,12 @@ export class WebsocketMessageAdapter {
|
|||
const closeReason = `Connection closed. ${code}: ${reason}`;
|
||||
this.privConnectionState = ConnectionState.Disconnected;
|
||||
this.privDisconnectDeferral.resolve();
|
||||
await this.privReceivingMessageQueue.drainAndDispose((pendingReceiveItem: ConnectionMessage) => {
|
||||
await this.privReceivingMessageQueue.drainAndDispose((): void => {
|
||||
// TODO: Events for these ?
|
||||
// Logger.instance.onEvent(new LoggingEvent(LogType.Warning, null, `Failed to process received message. Reason: ${closeReason}, Message: ${JSON.stringify(pendingReceiveItem)}`));
|
||||
}, closeReason);
|
||||
|
||||
await this.privSendMessageQueue.drainAndDispose((pendingSendItem: ISendItem) => {
|
||||
await this.privSendMessageQueue.drainAndDispose((pendingSendItem: ISendItem): void => {
|
||||
pendingSendItem.sendStatusDeferral.reject(closeReason);
|
||||
}, closeReason);
|
||||
}
|
||||
|
@ -311,12 +313,12 @@ export class WebsocketMessageAdapter {
|
|||
await this.sendRawMessage(sendItem);
|
||||
sendItem.sendStatusDeferral.resolve();
|
||||
} catch (sendError) {
|
||||
sendItem.sendStatusDeferral.reject(sendError);
|
||||
sendItem.sendStatusDeferral.reject(sendError as string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private onEvent = (event: ConnectionEvent): void => {
|
||||
private onEvent(event: ConnectionEvent): void {
|
||||
this.privConnectionEvents.onEvent(event);
|
||||
Events.instance.onEvent(event);
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import { LanguageUnderstandingModelImpl } from "../sdk/LanguageUnderstandingMode
|
|||
/**
|
||||
* @class AddedLmIntent
|
||||
*/
|
||||
// tslint:disable-next-line:max-classes-per-file
|
||||
// eslint-disable-next-line max-classes-per-file
|
||||
export class AddedLmIntent {
|
||||
public modelImpl: LanguageUnderstandingModelImpl;
|
||||
public intentName: string;
|
||||
|
|
|
@ -26,12 +26,12 @@ export class AgentConfig {
|
|||
|
||||
export interface IAgentConfig {
|
||||
botInfo: {
|
||||
commType: string,
|
||||
connectionId: string,
|
||||
conversationId: string,
|
||||
fromId: string
|
||||
commandsCulture: string,
|
||||
ttsAudioFormat: string
|
||||
commType: string;
|
||||
connectionId: string;
|
||||
conversationId: string;
|
||||
fromId: string;
|
||||
commandsCulture: string;
|
||||
ttsAudioFormat: string;
|
||||
};
|
||||
version: number;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ export class CognitiveSubscriptionKeyAuthentication implements IAuthentication {
|
|||
* @constructor
|
||||
* @param {string} subscriptionKey - The subscription key
|
||||
*/
|
||||
constructor(subscriptionKey: string) {
|
||||
public constructor(subscriptionKey: string) {
|
||||
if (!subscriptionKey) {
|
||||
throw new ArgumentNullError("subscriptionKey");
|
||||
}
|
||||
|
@ -36,7 +36,8 @@ export class CognitiveSubscriptionKeyAuthentication implements IAuthentication {
|
|||
* @public
|
||||
* @param {string} authFetchEventId - The id to fetch.
|
||||
*/
|
||||
public fetch = (authFetchEventId: string): Promise<AuthInfo> => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
public fetch(authFetchEventId: string): Promise<AuthInfo> {
|
||||
return Promise.resolve(this.privAuthInfo);
|
||||
}
|
||||
|
||||
|
@ -47,7 +48,8 @@ export class CognitiveSubscriptionKeyAuthentication implements IAuthentication {
|
|||
* @public
|
||||
* @param {string} authFetchEventId - The id to fetch.
|
||||
*/
|
||||
public fetchOnExpiry = (authFetchEventId: string): Promise<AuthInfo> => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
public fetchOnExpiry(authFetchEventId: string): Promise<AuthInfo> {
|
||||
return Promise.resolve(this.privAuthInfo);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ export class CognitiveTokenAuthentication implements IAuthentication {
|
|||
private privFetchCallback: (authFetchEventId: string) => Promise<string>;
|
||||
private privFetchOnExpiryCallback: (authFetchEventId: string) => Promise<string>;
|
||||
|
||||
constructor(fetchCallback: (authFetchEventId: string) => Promise<string>, fetchOnExpiryCallback: (authFetchEventId: string) => Promise<string>) {
|
||||
public constructor(fetchCallback: (authFetchEventId: string) => Promise<string>, fetchOnExpiryCallback: (authFetchEventId: string) => Promise<string>) {
|
||||
if (!fetchCallback) {
|
||||
throw new ArgumentNullError("fetchCallback");
|
||||
}
|
||||
|
@ -24,11 +24,11 @@ export class CognitiveTokenAuthentication implements IAuthentication {
|
|||
this.privFetchOnExpiryCallback = fetchOnExpiryCallback;
|
||||
}
|
||||
|
||||
public fetch = (authFetchEventId: string): Promise<AuthInfo> => {
|
||||
return this.privFetchCallback(authFetchEventId).then((token: string) => new AuthInfo(AuthHeader, CognitiveTokenAuthentication.privTokenPrefix + token));
|
||||
public fetch(authFetchEventId: string): Promise<AuthInfo> {
|
||||
return this.privFetchCallback(authFetchEventId).then((token: string): AuthInfo => new AuthInfo(AuthHeader, CognitiveTokenAuthentication.privTokenPrefix + token));
|
||||
}
|
||||
|
||||
public fetchOnExpiry = (authFetchEventId: string): Promise<AuthInfo> => {
|
||||
return this.privFetchOnExpiryCallback(authFetchEventId).then((token: string) => new AuthInfo(AuthHeader, CognitiveTokenAuthentication.privTokenPrefix + token));
|
||||
public fetchOnExpiry(authFetchEventId: string): Promise<AuthInfo> {
|
||||
return this.privFetchOnExpiryCallback(authFetchEventId).then((token: string): AuthInfo => new AuthInfo(AuthHeader, CognitiveTokenAuthentication.privTokenPrefix + token));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,8 +5,8 @@ import {
|
|||
ServicePropertiesPropertyName,
|
||||
} from "../common.speech/Exports";
|
||||
import { IConnection, IStringDictionary } from "../common/Exports";
|
||||
import { OutputFormat, PropertyId } from "../sdk/Exports";
|
||||
import { AuthInfo, IConnectionFactory, RecognitionMode, RecognizerConfig, WebsocketMessageFormatter } from "./Exports";
|
||||
import { PropertyId } from "../sdk/Exports";
|
||||
import { AuthInfo, IConnectionFactory, RecognizerConfig } from "./Exports";
|
||||
import { QueryParameterNames } from "./QueryParameterNames";
|
||||
|
||||
export abstract class ConnectionFactoryBase implements IConnectionFactory {
|
||||
|
@ -69,9 +69,9 @@ export abstract class ConnectionFactoryBase implements IConnectionFactory {
|
|||
queryParams,
|
||||
endpoint);
|
||||
|
||||
const serviceProperties: IStringDictionary<string> = JSON.parse(config.parameters.getProperty(ServicePropertiesPropertyName, "{}"));
|
||||
const serviceProperties: IStringDictionary<string> = JSON.parse(config.parameters.getProperty(ServicePropertiesPropertyName, "{}")) as IStringDictionary<string>;
|
||||
|
||||
Object.keys(serviceProperties).forEach((value: string, num: number, array: string[]) => {
|
||||
Object.keys(serviceProperties).forEach((value: string): void => {
|
||||
queryParams[value] = serviceProperties[value];
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
/* eslint-disable max-classes-per-file */
|
||||
import {
|
||||
ProxyInfo,
|
||||
WebsocketConnection,
|
||||
|
@ -15,15 +16,13 @@ import { QueryParameterNames } from "./QueryParameterNames";
|
|||
|
||||
export class DialogConnectionFactory extends ConnectionFactoryBase {
|
||||
|
||||
private static Constants: any = class {
|
||||
private static ApiKey: string = "api";
|
||||
private static BaseUrl: string = "convai.speech";
|
||||
};
|
||||
private static readonly ApiKey: string = "api";
|
||||
private static readonly BaseUrl: string = "convai.speech";
|
||||
|
||||
public create = (
|
||||
public create(
|
||||
config: RecognizerConfig,
|
||||
authInfo: AuthInfo,
|
||||
connectionId?: string): IConnection => {
|
||||
connectionId?: string): IConnection {
|
||||
|
||||
const applicationId: string = config.parameters.getProperty(PropertyId.Conversation_ApplicationId, "");
|
||||
const dialogType: string = config.parameters.getProperty(PropertyId.Conversation_DialogType);
|
||||
|
@ -66,9 +65,9 @@ export class DialogConnectionFactory extends ConnectionFactoryBase {
|
|||
const hostSuffix: string = ConnectionFactoryBase.getHostSuffix(region);
|
||||
const host: string = config.parameters.getProperty(
|
||||
PropertyId.SpeechServiceConnection_Host,
|
||||
`wss://${region}.${DialogConnectionFactory.Constants.BaseUrl}${hostSuffix}`);
|
||||
`wss://${region}.${DialogConnectionFactory.BaseUrl}${hostSuffix}`);
|
||||
const standardizedHost: string = host.endsWith("/") ? host : host + "/";
|
||||
endpoint = `${standardizedHost}${resourceInfix}${DialogConnectionFactory.Constants.ApiKey}/${version}`;
|
||||
endpoint = `${standardizedHost}${resourceInfix}${DialogConnectionFactory.ApiKey}/${version}`;
|
||||
}
|
||||
|
||||
this.setCommonUrlParams(config, queryParams, endpoint);
|
||||
|
|
|
@ -85,17 +85,19 @@ export class DialogServiceAdapter extends ServiceRecognizerBase {
|
|||
|
||||
this.privEvents = new EventSource<DialogEvent>();
|
||||
this.privDialogServiceConnector = dialogServiceConnector;
|
||||
this.receiveMessageOverride = this.receiveDialogMessageOverride;
|
||||
this.receiveMessageOverride = (): Promise<void> => this.receiveDialogMessageOverride();
|
||||
this.privTurnStateManager = new DialogServiceTurnStateManager();
|
||||
this.recognizeOverride = this.listenOnce;
|
||||
this.postConnectImplOverride = this.dialogConnectImpl;
|
||||
this.configConnectionOverride = this.configConnection;
|
||||
this.disconnectOverride = this.privDisconnect;
|
||||
this.recognizeOverride =
|
||||
(recoMode: RecognitionMode, successCallback: (e: SpeechRecognitionResult) => void, errorCallback: (e: string) => void): Promise<void> =>
|
||||
this.listenOnce(recoMode, successCallback, errorCallback);
|
||||
this.postConnectImplOverride = (connection: Promise<IConnection>): Promise<IConnection> => this.dialogConnectImpl(connection);
|
||||
this.configConnectionOverride = (connection: IConnection): Promise<IConnection> => this.configConnection(connection);
|
||||
this.disconnectOverride = (): Promise<void> => this.privDisconnect();
|
||||
this.privDialogAudioSource = audioSource;
|
||||
|
||||
this.agentConfigSent = false;
|
||||
this.privLastResult = null;
|
||||
this.connectionEvents.attach(async (connectionEvent: ConnectionEvent): Promise<void> => {
|
||||
this.connectionEvents.attach((connectionEvent: ConnectionEvent): void => {
|
||||
if (connectionEvent.name === "ConnectionClosedEvent") {
|
||||
this.terminateMessageLoop = true;
|
||||
}
|
||||
|
@ -110,6 +112,7 @@ export class DialogServiceAdapter extends ServiceRecognizerBase {
|
|||
context: {
|
||||
interactionId: interactionGuid
|
||||
},
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
messagePayload: JSON.parse(message),
|
||||
version: 0.5
|
||||
};
|
||||
|
@ -137,7 +140,7 @@ export class DialogServiceAdapter extends ServiceRecognizerBase {
|
|||
return;
|
||||
}
|
||||
|
||||
protected async processTypeSpecificMessages(connectionMessage: SpeechConnectionMessage): Promise<boolean> {
|
||||
protected processTypeSpecificMessages(connectionMessage: SpeechConnectionMessage): Promise<boolean> {
|
||||
|
||||
const resultProps: PropertyCollection = new PropertyCollection();
|
||||
if (connectionMessage.messageType === MessageType.Text) {
|
||||
|
@ -160,7 +163,7 @@ export class DialogServiceAdapter extends ServiceRecognizerBase {
|
|||
if (!!this.privDialogServiceConnector.recognized) {
|
||||
try {
|
||||
this.privDialogServiceConnector.recognized(this.privDialogServiceConnector, args);
|
||||
/* tslint:disable:no-empty */
|
||||
/* eslint-disable no-empty */
|
||||
} catch (error) {
|
||||
// Not going to let errors in the event handler
|
||||
// trip things up.
|
||||
|
@ -193,7 +196,7 @@ export class DialogServiceAdapter extends ServiceRecognizerBase {
|
|||
if (!!this.privDialogServiceConnector.recognizing) {
|
||||
try {
|
||||
this.privDialogServiceConnector.recognizing(this.privDialogServiceConnector, ev);
|
||||
/* tslint:disable:no-empty */
|
||||
/* eslint-disable no-empty */
|
||||
} catch (error) {
|
||||
// Not going to let errors in the event handler
|
||||
// trip things up.
|
||||
|
@ -226,7 +229,7 @@ export class DialogServiceAdapter extends ServiceRecognizerBase {
|
|||
if (!!this.privDialogServiceConnector.recognized) {
|
||||
try {
|
||||
this.privDialogServiceConnector.recognized(this.privDialogServiceConnector, event);
|
||||
/* tslint:disable:no-empty */
|
||||
/* eslint-disable no-empty */
|
||||
} catch (error) {
|
||||
// Not going to let errors in the event handler
|
||||
// trip things up.
|
||||
|
@ -264,7 +267,9 @@ export class DialogServiceAdapter extends ServiceRecognizerBase {
|
|||
default:
|
||||
break;
|
||||
}
|
||||
return processed;
|
||||
const defferal = new Deferred<boolean>();
|
||||
defferal.resolve(processed);
|
||||
return defferal.promise;
|
||||
}
|
||||
|
||||
// Cancels recognition.
|
||||
|
@ -294,7 +299,7 @@ export class DialogServiceAdapter extends ServiceRecognizerBase {
|
|||
|
||||
try {
|
||||
this.privDialogServiceConnector.canceled(this.privDialogServiceConnector, cancelEvent);
|
||||
/* tslint:disable:no-empty */
|
||||
/* eslint-disable no-empty */
|
||||
} catch { }
|
||||
|
||||
if (!!this.privSuccessCallback) {
|
||||
|
@ -313,7 +318,7 @@ export class DialogServiceAdapter extends ServiceRecognizerBase {
|
|||
try {
|
||||
this.privSuccessCallback(result);
|
||||
this.privSuccessCallback = undefined;
|
||||
/* tslint:disable:no-empty */
|
||||
/* eslint-disable no-empty */
|
||||
} catch { }
|
||||
}
|
||||
}
|
||||
|
@ -352,7 +357,7 @@ export class DialogServiceAdapter extends ServiceRecognizerBase {
|
|||
await conPromise;
|
||||
await preAudioPromise;
|
||||
} catch (error) {
|
||||
await this.cancelRecognition(this.privRequestSession.sessionId, this.privRequestSession.requestId, CancellationReason.Error, CancellationErrorCode.ConnectionFailure, error);
|
||||
await this.cancelRecognition(this.privRequestSession.sessionId, this.privRequestSession.requestId, CancellationReason.Error, CancellationErrorCode.ConnectionFailure, error as string);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
|
@ -364,8 +369,8 @@ export class DialogServiceAdapter extends ServiceRecognizerBase {
|
|||
|
||||
const audioSendPromise = this.sendAudio(audioNode);
|
||||
|
||||
// /* tslint:disable:no-empty */
|
||||
audioSendPromise.then(() => { /*add? return true;*/ }, async (error: string) => {
|
||||
// /* eslint-disable no-empty */
|
||||
audioSendPromise.then((): void => { /* add? return true;*/ }, async (error: string): Promise<void> => {
|
||||
await this.cancelRecognition(this.privRequestSession.sessionId, this.privRequestSession.requestId, CancellationReason.Error, CancellationErrorCode.RuntimeError, error);
|
||||
});
|
||||
}
|
||||
|
@ -476,7 +481,7 @@ export class DialogServiceAdapter extends ServiceRecognizerBase {
|
|||
this.privLastResult = null;
|
||||
} catch (e) {
|
||||
if (!!this.privErrorCallback) {
|
||||
this.privErrorCallback(e);
|
||||
this.privErrorCallback(e as string);
|
||||
}
|
||||
}
|
||||
// Only invoke the call back once.
|
||||
|
@ -490,10 +495,15 @@ export class DialogServiceAdapter extends ServiceRecognizerBase {
|
|||
break;
|
||||
|
||||
default:
|
||||
if (!this.processTypeSpecificMessages(connectionMessage)) {
|
||||
if (!!this.serviceEvents) {
|
||||
this.serviceEvents.onEvent(new ServiceEvent(connectionMessage.path.toLowerCase(), connectionMessage.textBody));
|
||||
try {
|
||||
const processed = await this.processTypeSpecificMessages(connectionMessage);
|
||||
if (!processed) {
|
||||
if (!!this.serviceEvents) {
|
||||
this.serviceEvents.onEvent(new ServiceEvent(connectionMessage.path.toLowerCase(), connectionMessage.textBody));
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
//
|
||||
}
|
||||
}
|
||||
const ret: Promise<void> = loop();
|
||||
|
@ -519,7 +529,7 @@ export class DialogServiceAdapter extends ServiceRecognizerBase {
|
|||
try {
|
||||
await this.receiveDialogMessageOverride();
|
||||
} catch (error) {
|
||||
await this.cancelRecognition(this.privRequestSession.sessionId, this.privRequestSession.requestId, CancellationReason.Error, CancellationErrorCode.RuntimeError, error);
|
||||
await this.cancelRecognition(this.privRequestSession.sessionId, this.privRequestSession.requestId, CancellationReason.Error, CancellationErrorCode.RuntimeError, error as string);
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
|
@ -529,7 +539,7 @@ export class DialogServiceAdapter extends ServiceRecognizerBase {
|
|||
private async configConnection(connection: IConnection): Promise<IConnection> {
|
||||
if (this.terminateMessageLoop) {
|
||||
this.terminateMessageLoop = false;
|
||||
return Promise.reject(`Connection to service terminated.`);
|
||||
return Promise.reject("Connection to service terminated.");
|
||||
}
|
||||
|
||||
await this.sendSpeechServiceConfig(connection, this.privRequestSession, this.privRecognizerConfig.SpeechServiceConfig.serialize());
|
||||
|
@ -545,7 +555,7 @@ export class DialogServiceAdapter extends ServiceRecognizerBase {
|
|||
await this.sendWaveHeader(connection);
|
||||
}
|
||||
|
||||
private sendAgentConfig = (connection: IConnection): Promise<void> => {
|
||||
private sendAgentConfig(connection: IConnection): Promise<void> {
|
||||
if (this.agentConfig && !this.agentConfigSent) {
|
||||
|
||||
if (this.privRecognizerConfig
|
||||
|
@ -573,7 +583,7 @@ export class DialogServiceAdapter extends ServiceRecognizerBase {
|
|||
return;
|
||||
}
|
||||
|
||||
private sendAgentContext = (connection: IConnection): Promise<void> => {
|
||||
private sendAgentContext(connection: IConnection): Promise<void> {
|
||||
const guid: string = createGuid();
|
||||
|
||||
const speechActivityTemplate = this.privDialogServiceConnector.properties.getProperty(PropertyId.Conversation_Speech_Activity_Template);
|
||||
|
@ -619,10 +629,10 @@ export class DialogServiceAdapter extends ServiceRecognizerBase {
|
|||
return ev;
|
||||
}
|
||||
|
||||
private handleResponseMessage = (responseMessage: SpeechConnectionMessage): void => {
|
||||
private handleResponseMessage(responseMessage: SpeechConnectionMessage): void {
|
||||
// "response" messages can contain either "message" (activity) or "MessageStatus" data. Fire the appropriate
|
||||
// event according to the message type that's specified.
|
||||
const responsePayload = JSON.parse(responseMessage.textBody);
|
||||
const responsePayload: { messageType: string } = JSON.parse(responseMessage.textBody) as { messageType: string };
|
||||
switch (responsePayload.messageType.toLowerCase()) {
|
||||
case "message":
|
||||
const responseRequestId = responseMessage.requestId.toUpperCase();
|
||||
|
@ -643,7 +653,7 @@ export class DialogServiceAdapter extends ServiceRecognizerBase {
|
|||
if (!!this.privDialogServiceConnector.activityReceived) {
|
||||
try {
|
||||
this.privDialogServiceConnector.activityReceived(this.privDialogServiceConnector, activity);
|
||||
/* tslint:disable:no-empty */
|
||||
/* eslint-disable-next-line no-empty */
|
||||
} catch (error) {
|
||||
// Not going to let errors in the event handler
|
||||
// trip things up.
|
||||
|
@ -657,7 +667,7 @@ export class DialogServiceAdapter extends ServiceRecognizerBase {
|
|||
this.privDialogServiceConnector.turnStatusReceived(
|
||||
this.privDialogServiceConnector,
|
||||
new TurnStatusReceivedEventArgs(responseMessage.textBody));
|
||||
/* tslint:disable:no-empty */
|
||||
/* eslint-disable-next-line no-empty */
|
||||
} catch (error) {
|
||||
// Not going to let errors in the event handler
|
||||
// trip things up.
|
||||
|
|
|
@ -13,14 +13,12 @@ export class DialogServiceTurnState {
|
|||
private privTimeoutToken: any;
|
||||
private privTurnManager: DialogServiceTurnStateManager;
|
||||
|
||||
constructor(manager: DialogServiceTurnStateManager, requestId: string) {
|
||||
public constructor(manager: DialogServiceTurnStateManager, requestId: string) {
|
||||
this.privRequestId = requestId;
|
||||
this.privIsCompleted = false;
|
||||
this.privAudioStream = null;
|
||||
this.privTurnManager = manager;
|
||||
this.resetTurnEndTimeout();
|
||||
// tslint:disable-next-line:no-console
|
||||
// console.info("DialogServiceTurnState debugturn start:" + this.privRequestId);
|
||||
}
|
||||
|
||||
public get audioStream(): PullAudioOutputStreamImpl {
|
||||
|
@ -33,8 +31,6 @@ export class DialogServiceTurnState {
|
|||
if (payload.messageDataStreamType === MessageDataStreamType.TextToSpeechAudio) {
|
||||
this.privAudioStream = AudioOutputStream.createPullStream() as PullAudioOutputStreamImpl;
|
||||
this.privAudioStream.format = (audioFormat !== undefined) ? audioFormat : AudioOutputFormatImpl.getDefaultOutputFormat();
|
||||
// tslint:disable-next-line:no-console
|
||||
// console.info("Audio start debugturn:" + this.privRequestId);
|
||||
}
|
||||
return this.privAudioStream;
|
||||
}
|
||||
|
@ -47,6 +43,7 @@ export class DialogServiceTurnState {
|
|||
|
||||
public complete(): void {
|
||||
if (this.privTimeoutToken !== undefined) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||
clearTimeout(this.privTimeoutToken);
|
||||
}
|
||||
this.endAudioStream();
|
||||
|
@ -54,15 +51,10 @@ export class DialogServiceTurnState {
|
|||
|
||||
private resetTurnEndTimeout(): void {
|
||||
if (this.privTimeoutToken !== undefined) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||
clearTimeout(this.privTimeoutToken);
|
||||
}
|
||||
// tslint:disable-next-line:no-console
|
||||
// console.info("Timeout reset debugturn:" + this.privRequestId);
|
||||
|
||||
this.privTimeoutToken = setTimeout((): void => {
|
||||
// tslint:disable-next-line:no-console
|
||||
// console.info("Timeout complete debugturn:" + this.privRequestId);
|
||||
|
||||
this.privTurnManager.CompleteTurn(this.privRequestId);
|
||||
return;
|
||||
}, 2000);
|
||||
|
|
|
@ -2,14 +2,12 @@
|
|||
// Licensed under the MIT license.
|
||||
|
||||
import { InvalidOperationError } from "../common/Error";
|
||||
import { AudioOutputStream, PullAudioOutputStreamImpl } from "../sdk/Audio/AudioOutputStream";
|
||||
import { DialogServiceTurnState } from "./DialogServiceTurnState";
|
||||
import { ActivityPayloadResponse } from "./ServiceMessages/ActivityResponsePayload";
|
||||
|
||||
export class DialogServiceTurnStateManager {
|
||||
private privTurnMap: Map<string, DialogServiceTurnState>;
|
||||
|
||||
constructor() {
|
||||
public constructor() {
|
||||
this.privTurnMap = new Map<string, DialogServiceTurnState>();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -23,9 +23,9 @@ export class DynamicGrammarBuilder {
|
|||
}
|
||||
|
||||
if (phrase instanceof Array) {
|
||||
this.privPhrases = this.privPhrases.concat(phrase as string[]);
|
||||
this.privPhrases = this.privPhrases.concat(phrase);
|
||||
} else {
|
||||
this.privPhrases.push(phrase as string);
|
||||
this.privPhrases.push(phrase);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,9 +41,9 @@ export class DynamicGrammarBuilder {
|
|||
}
|
||||
|
||||
if (grammar instanceof Array) {
|
||||
this.privGrammars = this.privGrammars.concat(grammar as string[]);
|
||||
this.privGrammars = this.privGrammars.concat(grammar);
|
||||
} else {
|
||||
this.privGrammars.push(grammar as string);
|
||||
this.privGrammars.push(grammar);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ export class DynamicGrammarBuilder {
|
|||
if (undefined !== this.privPhrases && 0 !== this.privPhrases.length) {
|
||||
const retPhrases: IDynamicGrammarGeneric[] = [];
|
||||
|
||||
this.privPhrases.forEach((value: string, index: number, array: string[]): void => {
|
||||
this.privPhrases.forEach((value: string): void => {
|
||||
retPhrases.push({
|
||||
Text: value,
|
||||
});
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
// for dynamic grammars.
|
||||
|
||||
/**
|
||||
* Top level grammar node
|
||||
* Top level grammar node
|
||||
*/
|
||||
export interface IDynamicGrammar {
|
||||
ReferenceGrammars?: string[];
|
||||
|
|
|
@ -24,10 +24,10 @@ import { HeaderNames } from "./HeaderNames";
|
|||
|
||||
export class IntentConnectionFactory extends ConnectionFactoryBase {
|
||||
|
||||
public create = (
|
||||
public create(
|
||||
config: RecognizerConfig,
|
||||
authInfo: AuthInfo,
|
||||
connectionId?: string): IConnection => {
|
||||
connectionId?: string): IConnection {
|
||||
|
||||
let endpoint: string = config.parameters.getProperty(PropertyId.SpeechServiceConnection_Endpoint);
|
||||
if (!endpoint) {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the MIT license.
|
||||
|
||||
import {
|
||||
Deferred,
|
||||
IAudioSource,
|
||||
MessageType,
|
||||
} from "../common/Exports";
|
||||
|
@ -15,7 +16,6 @@ import {
|
|||
PropertyCollection,
|
||||
PropertyId,
|
||||
ResultReason,
|
||||
SpeechRecognitionResult,
|
||||
} from "../sdk/Exports";
|
||||
import {
|
||||
AddedLmIntent,
|
||||
|
@ -31,10 +31,10 @@ import { IConnectionFactory } from "./IConnectionFactory";
|
|||
import { RecognizerConfig } from "./RecognizerConfig";
|
||||
import { SpeechConnectionMessage } from "./SpeechConnectionMessage.Internal";
|
||||
|
||||
// tslint:disable-next-line:max-classes-per-file
|
||||
// eslint-disable-next-line max-classes-per-file
|
||||
export class IntentServiceRecognizer extends ServiceRecognizerBase {
|
||||
private privIntentRecognizer: IntentRecognizer;
|
||||
private privAddedLmIntents: { [id: string]: AddedLmIntent; };
|
||||
private privAddedLmIntents: { [id: string]: AddedLmIntent };
|
||||
private privIntentDataSent: boolean;
|
||||
private privUmbrellaIntent: AddedLmIntent;
|
||||
private privPendingIntentArgs: IntentRecognitionEventArgs;
|
||||
|
@ -50,13 +50,13 @@ export class IntentServiceRecognizer extends ServiceRecognizerBase {
|
|||
this.privIntentDataSent = false;
|
||||
}
|
||||
|
||||
public setIntents(addedIntents: { [id: string]: AddedLmIntent; }, umbrellaIntent: AddedLmIntent): void {
|
||||
public setIntents(addedIntents: { [id: string]: AddedLmIntent }, umbrellaIntent: AddedLmIntent): void {
|
||||
this.privAddedLmIntents = addedIntents;
|
||||
this.privUmbrellaIntent = umbrellaIntent;
|
||||
this.privIntentDataSent = true;
|
||||
}
|
||||
|
||||
protected async processTypeSpecificMessages(connectionMessage: SpeechConnectionMessage): Promise<boolean> {
|
||||
protected processTypeSpecificMessages(connectionMessage: SpeechConnectionMessage): Promise<boolean> {
|
||||
|
||||
let result: IntentRecognitionResult;
|
||||
let ev: IntentRecognitionEventArgs;
|
||||
|
@ -91,7 +91,7 @@ export class IntentServiceRecognizer extends ServiceRecognizerBase {
|
|||
if (!!this.privIntentRecognizer.recognizing) {
|
||||
try {
|
||||
this.privIntentRecognizer.recognizing(this.privIntentRecognizer, ev);
|
||||
/* tslint:disable:no-empty */
|
||||
/* eslint-disable no-empty */
|
||||
} catch (error) {
|
||||
// Not going to let errors in the event handler
|
||||
// trip things up.
|
||||
|
@ -116,11 +116,11 @@ export class IntentServiceRecognizer extends ServiceRecognizerBase {
|
|||
|
||||
ev = new IntentRecognitionEventArgs(result, result.offset, this.privRequestSession.sessionId);
|
||||
|
||||
const sendEvent: () => void = () => {
|
||||
const sendEvent: () => void = (): void => {
|
||||
if (!!this.privIntentRecognizer.recognized) {
|
||||
try {
|
||||
this.privIntentRecognizer.recognized(this.privIntentRecognizer, ev);
|
||||
/* tslint:disable:no-empty */
|
||||
/* eslint-disable no-empty */
|
||||
} catch (error) {
|
||||
// Not going to let errors in the event handler
|
||||
// trip things up.
|
||||
|
@ -133,7 +133,7 @@ export class IntentServiceRecognizer extends ServiceRecognizerBase {
|
|||
this.privSuccessCallback(result);
|
||||
} catch (e) {
|
||||
if (!!this.privErrorCallback) {
|
||||
this.privErrorCallback(e);
|
||||
this.privErrorCallback(e as string);
|
||||
}
|
||||
}
|
||||
// Only invoke the call back once.
|
||||
|
@ -170,7 +170,7 @@ export class IntentServiceRecognizer extends ServiceRecognizerBase {
|
|||
}
|
||||
|
||||
// Odd... Not sure this can happen
|
||||
ev = new IntentRecognitionEventArgs(new IntentRecognitionResult(), 0 /*TODO*/, this.privRequestSession.sessionId);
|
||||
ev = new IntentRecognitionEventArgs(new IntentRecognitionResult(), 0, this.privRequestSession.sessionId);
|
||||
}
|
||||
|
||||
const intentResponse: IntentResponse = IntentResponse.fromJSON(connectionMessage.textBody);
|
||||
|
@ -219,7 +219,7 @@ export class IntentServiceRecognizer extends ServiceRecognizerBase {
|
|||
if (!!this.privIntentRecognizer.recognized) {
|
||||
try {
|
||||
this.privIntentRecognizer.recognized(this.privIntentRecognizer, ev);
|
||||
/* tslint:disable:no-empty */
|
||||
/* eslint-disable no-empty */
|
||||
} catch (error) {
|
||||
// Not going to let errors in the event handler
|
||||
// trip things up.
|
||||
|
@ -232,7 +232,7 @@ export class IntentServiceRecognizer extends ServiceRecognizerBase {
|
|||
this.privSuccessCallback(ev.result);
|
||||
} catch (e) {
|
||||
if (!!this.privErrorCallback) {
|
||||
this.privErrorCallback(e);
|
||||
this.privErrorCallback(e as string);
|
||||
}
|
||||
}
|
||||
// Only invoke the call back once.
|
||||
|
@ -246,7 +246,9 @@ export class IntentServiceRecognizer extends ServiceRecognizerBase {
|
|||
default:
|
||||
break;
|
||||
}
|
||||
return processed;
|
||||
const defferal = new Deferred<boolean>();
|
||||
defferal.resolve(processed);
|
||||
return defferal.promise;
|
||||
}
|
||||
|
||||
// Cancels recognition.
|
||||
|
@ -271,7 +273,7 @@ export class IntentServiceRecognizer extends ServiceRecognizerBase {
|
|||
sessionId);
|
||||
try {
|
||||
this.privIntentRecognizer.canceled(this.privIntentRecognizer, cancelEvent);
|
||||
/* tslint:disable:no-empty */
|
||||
/* eslint-disable no-empty */
|
||||
} catch { }
|
||||
}
|
||||
|
||||
|
@ -291,7 +293,7 @@ export class IntentServiceRecognizer extends ServiceRecognizerBase {
|
|||
try {
|
||||
this.privSuccessCallback(result);
|
||||
this.privSuccessCallback = undefined;
|
||||
/* tslint:disable:no-empty */
|
||||
/* eslint-disable no-empty */
|
||||
} catch { }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// tslint:disable:max-classes-per-file
|
||||
/* eslint-disable max-classes-per-file */
|
||||
|
||||
import { EventType, PlatformEvent } from "../common/Exports";
|
||||
|
||||
|
@ -9,7 +8,7 @@ export class SpeechRecognitionEvent extends PlatformEvent {
|
|||
private privRequestId: string;
|
||||
private privSessionId: string;
|
||||
|
||||
constructor(eventName: string, requestId: string, sessionId: string, eventType: EventType = EventType.Info) {
|
||||
public constructor(eventName: string, requestId: string, sessionId: string, eventType: EventType = EventType.Info) {
|
||||
super(eventName, eventType);
|
||||
|
||||
this.privRequestId = requestId;
|
||||
|
@ -29,7 +28,7 @@ export class RecognitionTriggeredEvent extends SpeechRecognitionEvent {
|
|||
private privAudioSourceId: string;
|
||||
private privAudioNodeId: string;
|
||||
|
||||
constructor(requestId: string, sessionId: string, audioSourceId: string, audioNodeId: string) {
|
||||
public constructor(requestId: string, sessionId: string, audioSourceId: string, audioNodeId: string) {
|
||||
super("RecognitionTriggeredEvent", requestId, sessionId);
|
||||
|
||||
this.privAudioSourceId = audioSourceId;
|
||||
|
@ -49,7 +48,7 @@ export class ListeningStartedEvent extends SpeechRecognitionEvent {
|
|||
private privAudioSourceId: string;
|
||||
private privAudioNodeId: string;
|
||||
|
||||
constructor(requestId: string, sessionId: string, audioSourceId: string, audioNodeId: string) {
|
||||
public constructor(requestId: string, sessionId: string, audioSourceId: string, audioNodeId: string) {
|
||||
super("ListeningStartedEvent", requestId, sessionId);
|
||||
this.privAudioSourceId = audioSourceId;
|
||||
this.privAudioNodeId = audioNodeId;
|
||||
|
@ -67,7 +66,7 @@ export class ListeningStartedEvent extends SpeechRecognitionEvent {
|
|||
export class ConnectingToServiceEvent extends SpeechRecognitionEvent {
|
||||
private privAuthFetchEventid: string;
|
||||
|
||||
constructor(requestId: string, authFetchEventid: string, sessionId: string) {
|
||||
public constructor(requestId: string, authFetchEventid: string, sessionId: string) {
|
||||
super("ConnectingToServiceEvent", requestId, sessionId);
|
||||
this.privAuthFetchEventid = authFetchEventid;
|
||||
}
|
||||
|
@ -82,7 +81,7 @@ export class RecognitionStartedEvent extends SpeechRecognitionEvent {
|
|||
private privAudioNodeId: string;
|
||||
private privAuthFetchEventId: string;
|
||||
|
||||
constructor(requestId: string, audioSourceId: string, audioNodeId: string, authFetchEventId: string, sessionId: string) {
|
||||
public constructor(requestId: string, audioSourceId: string, audioNodeId: string, authFetchEventId: string, sessionId: string) {
|
||||
super("RecognitionStartedEvent", requestId, sessionId);
|
||||
|
||||
this.privAudioSourceId = audioSourceId;
|
||||
|
@ -124,7 +123,7 @@ export class RecognitionEndedEvent extends SpeechRecognitionEvent {
|
|||
private privStatus: RecognitionCompletionStatus;
|
||||
private privError: string;
|
||||
|
||||
constructor(
|
||||
public constructor(
|
||||
requestId: string,
|
||||
audioSourceId: string,
|
||||
audioNodeId: string,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// tslint:disable:max-classes-per-file
|
||||
/* eslint-disable max-classes-per-file */
|
||||
|
||||
import { PropertyCollection, PropertyId } from "../sdk/Exports";
|
||||
|
||||
|
@ -25,7 +25,7 @@ export class RecognizerConfig {
|
|||
private privParameters: PropertyCollection;
|
||||
private privMaxRetryCount: number;
|
||||
|
||||
constructor(
|
||||
public constructor(
|
||||
speechServiceConfig: SpeechServiceConfig,
|
||||
parameters: PropertyCollection) {
|
||||
this.privSpeechServiceConfig = speechServiceConfig ? speechServiceConfig : new SpeechServiceConfig(new Context(null));
|
||||
|
@ -80,8 +80,8 @@ export class RecognizerConfig {
|
|||
return this.parameters.getProperty(PropertyId.SpeechServiceConnection_RecognitionEndpointVersion, undefined);
|
||||
}
|
||||
|
||||
public get sourceLanguageModels(): { language: string, endpoint: string }[] {
|
||||
const models: { language: string, endpoint: string }[] = [];
|
||||
public get sourceLanguageModels(): { language: string; endpoint: string }[] {
|
||||
const models: { language: string; endpoint: string }[] = [];
|
||||
let modelsExist: boolean = false;
|
||||
if (this.autoDetectSourceLanguages !== undefined) {
|
||||
for (const language of this.autoDetectSourceLanguages.split(",")) {
|
||||
|
@ -108,16 +108,17 @@ export class SpeechServiceConfig {
|
|||
private context: Context;
|
||||
private recognition: string;
|
||||
|
||||
constructor(context: Context) {
|
||||
public constructor(context: Context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public serialize = (): string => {
|
||||
return JSON.stringify(this, (key: any, value: any): any => {
|
||||
public serialize(): string {
|
||||
return JSON.stringify(this, (key: any, value: { [k: string]: any }): any => {
|
||||
if (value && typeof value === "object") {
|
||||
const replacement: any = {};
|
||||
const replacement: { [k: string ]: any } = {};
|
||||
for (const k in value) {
|
||||
if (Object.hasOwnProperty.call(value, k)) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
replacement[k && k.charAt(0).toLowerCase() + k.substring(1)] = value[k];
|
||||
}
|
||||
}
|
||||
|
@ -145,7 +146,7 @@ export class Context {
|
|||
public os: OS;
|
||||
public audio: ISpeechConfigAudio;
|
||||
|
||||
constructor(os: OS) {
|
||||
public constructor(os: OS) {
|
||||
this.system = new System();
|
||||
this.os = os;
|
||||
}
|
||||
|
@ -157,7 +158,7 @@ export class System {
|
|||
public build: string;
|
||||
public lang: string;
|
||||
|
||||
constructor() {
|
||||
public constructor() {
|
||||
// Note: below will be patched for official builds.
|
||||
const SPEECHSDK_CLIENTSDK_VERSION = "1.15.0-alpha.0.1";
|
||||
|
||||
|
@ -173,7 +174,7 @@ export class OS {
|
|||
public name: string;
|
||||
public version: string;
|
||||
|
||||
constructor(platform: string, name: string, version: string) {
|
||||
public constructor(platform: string, name: string, version: string) {
|
||||
this.platform = platform;
|
||||
this.name = name;
|
||||
this.version = version;
|
||||
|
@ -185,7 +186,7 @@ export class Device {
|
|||
public model: string;
|
||||
public version: string;
|
||||
|
||||
constructor(manufacturer: string, model: string, version: string) {
|
||||
public constructor(manufacturer: string, model: string, version: string) {
|
||||
this.manufacturer = manufacturer;
|
||||
this.model = model;
|
||||
this.version = version;
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import { Z_NO_COMPRESSION } from "zlib";
|
||||
import { ReplayableAudioNode } from "../common.browser/Exports";
|
||||
import {
|
||||
createNoDashGuid,
|
||||
|
@ -42,7 +41,7 @@ export class RequestSession {
|
|||
private privInTurn: boolean = false;
|
||||
private privConnectionAttempts: number = 0;
|
||||
|
||||
constructor(audioSourceId: string) {
|
||||
public constructor(audioSourceId: string) {
|
||||
this.privAudioSourceId = audioSourceId;
|
||||
this.privRequestId = createNoDashGuid();
|
||||
this.privAudioNodeId = createNoDashGuid();
|
||||
|
@ -109,7 +108,7 @@ export class RequestSession {
|
|||
this.onEvent(new RecognitionTriggeredEvent(this.requestId, this.privSessionId, this.privAudioSourceId, this.privAudioNodeId));
|
||||
}
|
||||
|
||||
public async onAudioSourceAttachCompleted(audioNode: ReplayableAudioNode, isError: boolean, error?: string): Promise<void> {
|
||||
public async onAudioSourceAttachCompleted(audioNode: ReplayableAudioNode, isError: boolean): Promise<void> {
|
||||
this.privAudioNode = audioNode;
|
||||
this.privIsAudioNodeDetached = false;
|
||||
|
||||
|
@ -120,18 +119,19 @@ export class RequestSession {
|
|||
}
|
||||
}
|
||||
|
||||
public onPreConnectionStart = (authFetchEventId: string, connectionId: string): void => {
|
||||
public onPreConnectionStart(authFetchEventId: string, connectionId: string): void {
|
||||
this.privAuthFetchEventId = authFetchEventId;
|
||||
this.privSessionId = connectionId;
|
||||
this.onEvent(new ConnectingToServiceEvent(this.privRequestId, this.privAuthFetchEventId, this.privSessionId));
|
||||
}
|
||||
|
||||
public async onAuthCompleted(isError: boolean, error?: string): Promise<void> {
|
||||
public async onAuthCompleted(isError: boolean): Promise<void> {
|
||||
if (isError) {
|
||||
await this.onComplete();
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
public async onConnectionEstablishCompleted(statusCode: number, reason?: string): Promise<void> {
|
||||
if (statusCode === 200) {
|
||||
this.onEvent(new RecognitionStartedEvent(this.requestId, this.privAudioSourceId, this.privAudioNodeId, this.privAuthFetchEventId, this.privSessionId));
|
||||
|
@ -159,17 +159,17 @@ export class RequestSession {
|
|||
}
|
||||
}
|
||||
|
||||
public onSpeechContext = (): void => {
|
||||
public onSpeechContext(): void {
|
||||
this.privRequestId = createNoDashGuid();
|
||||
}
|
||||
|
||||
public onServiceTurnStartResponse = (): void => {
|
||||
public onServiceTurnStartResponse(): void {
|
||||
if (!!this.privTurnDeferral && !!this.privInTurn) {
|
||||
// What? How are we starting a turn with another not done?
|
||||
this.privTurnDeferral.reject("Another turn started before current completed.");
|
||||
// Avoid UnhandledPromiseRejection if privTurnDeferral is not being awaited
|
||||
/* tslint:disable:no-empty */
|
||||
this.privTurnDeferral.promise.then().catch(() => { });
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
this.privTurnDeferral.promise.then().catch((): void => { });
|
||||
}
|
||||
this.privInTurn = true;
|
||||
this.privTurnDeferral = new Deferred<void>();
|
||||
|
@ -202,7 +202,7 @@ export class RequestSession {
|
|||
this.privConnectionAttempts++;
|
||||
}
|
||||
|
||||
public async dispose(error?: string): Promise<void> {
|
||||
public async dispose(): Promise<void> {
|
||||
if (!this.privIsDisposed) {
|
||||
// we should have completed by now. If we did not its an unknown error.
|
||||
this.privIsDisposed = true;
|
||||
|
@ -210,12 +210,14 @@ export class RequestSession {
|
|||
await detachable.detach();
|
||||
}
|
||||
|
||||
this.privServiceTelemetryListener?.dispose();
|
||||
if (!!this.privServiceTelemetryListener) {
|
||||
this.privServiceTelemetryListener.dispose();
|
||||
}
|
||||
this.privIsRecognizing = false;
|
||||
}
|
||||
}
|
||||
|
||||
public getTelemetry = (): string => {
|
||||
public getTelemetry(): string {
|
||||
if (this.privServiceTelemetryListener.hasTelemetry) {
|
||||
return this.privServiceTelemetryListener.getTelemetry();
|
||||
} else {
|
||||
|
@ -232,7 +234,7 @@ export class RequestSession {
|
|||
this.privIsSpeechEnded = true;
|
||||
}
|
||||
|
||||
protected onEvent = (event: SpeechRecognitionEvent): void => {
|
||||
protected onEvent(event: SpeechRecognitionEvent): void {
|
||||
if (!!this.privServiceTelemetryListener) {
|
||||
this.privServiceTelemetryListener.onEvent(event);
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
export interface IActivityPayloadResponse {
|
||||
conversationId: string;
|
||||
messageDataStreamType: number;
|
||||
messagePayload: any;
|
||||
messagePayload: string | object;
|
||||
version: number;
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@ export class ActivityPayloadResponse implements IActivityPayloadResponse {
|
|||
private privActivityResponse: IActivityPayloadResponse;
|
||||
|
||||
private constructor(json: string) {
|
||||
this.privActivityResponse = JSON.parse(json);
|
||||
this.privActivityResponse = JSON.parse(json) as IActivityPayloadResponse;
|
||||
}
|
||||
|
||||
public static fromJSON(json: string): ActivityPayloadResponse {
|
||||
|
@ -28,7 +28,7 @@ export class ActivityPayloadResponse implements IActivityPayloadResponse {
|
|||
return this.privActivityResponse.messageDataStreamType;
|
||||
}
|
||||
|
||||
public get messagePayload(): any {
|
||||
public get messagePayload(): string | object {
|
||||
return this.privActivityResponse.messagePayload;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,8 +33,8 @@ export class DetailedSpeechPhrase implements IDetailedSpeechPhrase {
|
|||
private privDetailedSpeechPhrase: IDetailedSpeechPhrase;
|
||||
|
||||
private constructor(json: string) {
|
||||
this.privDetailedSpeechPhrase = JSON.parse(json);
|
||||
this.privDetailedSpeechPhrase.RecognitionStatus = (RecognitionStatus as any)[this.privDetailedSpeechPhrase.RecognitionStatus];
|
||||
this.privDetailedSpeechPhrase = JSON.parse(json) as IDetailedSpeechPhrase;
|
||||
this.privDetailedSpeechPhrase.RecognitionStatus = RecognitionStatus[this.privDetailedSpeechPhrase.RecognitionStatus as unknown as keyof typeof RecognitionStatus];
|
||||
}
|
||||
|
||||
public static fromJSON(json: string): DetailedSpeechPhrase {
|
||||
|
|
|
@ -25,7 +25,7 @@ export class IntentResponse implements IIntentResponse {
|
|||
private privIntentResponse: IIntentResponse;
|
||||
|
||||
private constructor(json: string) {
|
||||
this.privIntentResponse = JSON.parse(json);
|
||||
this.privIntentResponse = JSON.parse(json) as IIntentResponse;
|
||||
}
|
||||
|
||||
public static fromJSON(json: string): IntentResponse {
|
||||
|
|
|
@ -22,8 +22,8 @@ export class SimpleSpeechPhrase implements ISimpleSpeechPhrase {
|
|||
private privSimpleSpeechPhrase: ISimpleSpeechPhrase;
|
||||
|
||||
private constructor(json: string) {
|
||||
this.privSimpleSpeechPhrase = JSON.parse(json);
|
||||
this.privSimpleSpeechPhrase.RecognitionStatus = (RecognitionStatus as any)[this.privSimpleSpeechPhrase.RecognitionStatus];
|
||||
this.privSimpleSpeechPhrase = JSON.parse(json) as ISimpleSpeechPhrase;
|
||||
this.privSimpleSpeechPhrase.RecognitionStatus = RecognitionStatus[this.privSimpleSpeechPhrase.RecognitionStatus as unknown as keyof typeof RecognitionStatus];
|
||||
}
|
||||
|
||||
public static fromJSON(json: string): SimpleSpeechPhrase {
|
||||
|
|
|
@ -10,7 +10,7 @@ export class SpeechDetected implements ISpeechDetected {
|
|||
private privSpeechStartDetected: ISpeechDetected;
|
||||
|
||||
private constructor(json: string) {
|
||||
this.privSpeechStartDetected = JSON.parse(json);
|
||||
this.privSpeechStartDetected = JSON.parse(json) as ISpeechDetected;
|
||||
}
|
||||
|
||||
public static fromJSON(json: string): SpeechDetected {
|
||||
|
|
|
@ -16,7 +16,7 @@ export class SpeechHypothesis implements ISpeechHypothesis {
|
|||
private privSpeechHypothesis: ISpeechHypothesis;
|
||||
|
||||
private constructor(json: string) {
|
||||
this.privSpeechHypothesis = JSON.parse(json);
|
||||
this.privSpeechHypothesis = JSON.parse(json) as ISpeechHypothesis;
|
||||
}
|
||||
|
||||
public static fromJSON(json: string): SpeechHypothesis {
|
||||
|
|
|
@ -13,7 +13,7 @@ export class SpeechKeyword implements ISpeechKeyword {
|
|||
private privSpeechKeyword: ISpeechKeyword;
|
||||
|
||||
private constructor(json: string) {
|
||||
this.privSpeechKeyword = JSON.parse(json);
|
||||
this.privSpeechKeyword = JSON.parse(json) as ISpeechKeyword;
|
||||
}
|
||||
|
||||
public static fromJSON(json: string): SpeechKeyword {
|
||||
|
|
|
@ -31,7 +31,7 @@ export class SynthesisAudioMetadata implements ISynthesisAudioMetadata {
|
|||
private privSynthesisAudioMetadata: ISynthesisAudioMetadata;
|
||||
|
||||
private constructor(json: string) {
|
||||
this.privSynthesisAudioMetadata = JSON.parse(json);
|
||||
this.privSynthesisAudioMetadata = JSON.parse(json) as ISynthesisAudioMetadata;
|
||||
}
|
||||
|
||||
public static fromJSON(json: string): SynthesisAudioMetadata {
|
||||
|
|
|
@ -16,8 +16,8 @@ export class TranslationHypothesis implements ITranslationHypothesis {
|
|||
private privTranslationHypothesis: ITranslationHypothesis;
|
||||
|
||||
private constructor(json: string) {
|
||||
this.privTranslationHypothesis = JSON.parse(json);
|
||||
this.privTranslationHypothesis.Translation.TranslationStatus = (TranslationStatus as any)[this.privTranslationHypothesis.Translation.TranslationStatus];
|
||||
this.privTranslationHypothesis = JSON.parse(json) as ITranslationHypothesis;
|
||||
this.privTranslationHypothesis.Translation.TranslationStatus = TranslationStatus[this.privTranslationHypothesis.Translation.TranslationStatus as unknown as keyof typeof TranslationStatus];
|
||||
}
|
||||
|
||||
public static fromJSON(json: string): TranslationHypothesis {
|
||||
|
|
|
@ -20,14 +20,14 @@ export class TranslationPhrase implements ITranslationPhrase {
|
|||
|
||||
private constructor(phrase: ITranslationPhrase) {
|
||||
this.privTranslationPhrase = phrase;
|
||||
this.privTranslationPhrase.RecognitionStatus = (RecognitionStatus as any)[this.privTranslationPhrase.RecognitionStatus];
|
||||
this.privTranslationPhrase.RecognitionStatus = RecognitionStatus[this.privTranslationPhrase.RecognitionStatus as unknown as keyof typeof RecognitionStatus];
|
||||
if (this.privTranslationPhrase.Translation !== undefined) {
|
||||
this.privTranslationPhrase.Translation.TranslationStatus = (TranslationStatus as any)[this.privTranslationPhrase.Translation.TranslationStatus];
|
||||
this.privTranslationPhrase.Translation.TranslationStatus = TranslationStatus[this.privTranslationPhrase.Translation.TranslationStatus as unknown as keyof typeof TranslationStatus];
|
||||
}
|
||||
}
|
||||
|
||||
public static fromJSON(json: string): TranslationPhrase {
|
||||
return new TranslationPhrase(JSON.parse(json));
|
||||
return new TranslationPhrase(JSON.parse(json) as ITranslationPhrase);
|
||||
}
|
||||
|
||||
public static fromTranslationResponse(translationResponse: { SpeechPhrase: ITranslationPhrase }): TranslationPhrase {
|
||||
|
|
|
@ -13,8 +13,8 @@ export class TranslationSynthesisEnd implements ITranslationSynthesisEnd {
|
|||
private privSynthesisEnd: ITranslationSynthesisEnd;
|
||||
|
||||
private constructor(json: string) {
|
||||
this.privSynthesisEnd = JSON.parse(json);
|
||||
this.privSynthesisEnd.SynthesisStatus = (SynthesisStatus as any)[this.privSynthesisEnd.SynthesisStatus];
|
||||
this.privSynthesisEnd = JSON.parse(json) as ITranslationSynthesisEnd;
|
||||
this.privSynthesisEnd.SynthesisStatus = SynthesisStatus[this.privSynthesisEnd.SynthesisStatus as unknown as keyof typeof SynthesisStatus];
|
||||
}
|
||||
|
||||
public static fromJSON(json: string): TranslationSynthesisEnd {
|
||||
|
|
|
@ -11,7 +11,7 @@ export class TurnStatusResponsePayload implements ITurnStatusResponsePayload {
|
|||
private privMessageStatusResponse: ITurnStatusResponsePayload;
|
||||
|
||||
private constructor(json: string) {
|
||||
this.privMessageStatusResponse = JSON.parse(json);
|
||||
this.privMessageStatusResponse = JSON.parse(json) as ITurnStatusResponsePayload;
|
||||
}
|
||||
|
||||
public static fromJSON(json: string): TurnStatusResponsePayload {
|
||||
|
@ -37,6 +37,7 @@ export class TurnStatusResponsePayload implements ITurnStatusResponsePayload {
|
|||
case "TimedOut":
|
||||
return 429;
|
||||
default:
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||
return this.privMessageStatusResponse.statusCode;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,11 +54,11 @@ export abstract class ServiceRecognizerBase implements IDisposable {
|
|||
|
||||
// A promise for a configured connection.
|
||||
// Do not consume directly, call fetchConnection instead.
|
||||
private privConnectionConfigurationPromise: Promise<IConnection>;
|
||||
private privConnectionConfigurationPromise: Promise<IConnection> = undefined;
|
||||
|
||||
// A promise for a connection, but one that has not had the speech context sent yet.
|
||||
// Do not consume directly, call fetchConnection instead.
|
||||
private privConnectionPromise: Promise<IConnection>;
|
||||
private privConnectionPromise: Promise<IConnection> = undefined;
|
||||
private privAuthFetchEventId: string;
|
||||
private privIsDisposed: boolean;
|
||||
private privMustReportEndOfStream: boolean;
|
||||
|
@ -119,7 +119,7 @@ export abstract class ServiceRecognizerBase implements IDisposable {
|
|||
this.privSetTimeout = Timeout.setTimeout;
|
||||
}
|
||||
|
||||
this.connectionEvents.attach(async (connectionEvent: ConnectionEvent): Promise<void> => {
|
||||
this.connectionEvents.attach((connectionEvent: ConnectionEvent): void => {
|
||||
if (connectionEvent.name === "ConnectionClosedEvent") {
|
||||
const connectionClosedEvent = connectionEvent as ConnectionClosedEvent;
|
||||
if (connectionClosedEvent.statusCode === 1003 ||
|
||||
|
@ -128,9 +128,9 @@ export abstract class ServiceRecognizerBase implements IDisposable {
|
|||
connectionClosedEvent.statusCode === 4000 ||
|
||||
this.privRequestSession.numConnectionAttempts > this.privRecognizerConfig.maxRetryCount
|
||||
) {
|
||||
await this.cancelRecognitionLocal(CancellationReason.Error,
|
||||
void this.cancelRecognitionLocal(CancellationReason.Error,
|
||||
connectionClosedEvent.statusCode === 1007 ? CancellationErrorCode.BadRequestParameters : CancellationErrorCode.ConnectionFailure,
|
||||
connectionClosedEvent.reason + " websocket error code: " + connectionClosedEvent.statusCode);
|
||||
`${connectionClosedEvent.reason} websocket error code: ${connectionClosedEvent.statusCode}`);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -166,7 +166,7 @@ export abstract class ServiceRecognizerBase implements IDisposable {
|
|||
|
||||
public async dispose(reason?: string): Promise<void> {
|
||||
this.privIsDisposed = true;
|
||||
if (this.privConnectionConfigurationPromise) {
|
||||
if (this.privConnectionConfigurationPromise !== undefined) {
|
||||
try {
|
||||
const connection: IConnection = await this.privConnectionConfigurationPromise;
|
||||
await connection.dispose(reason);
|
||||
|
@ -189,7 +189,7 @@ export abstract class ServiceRecognizerBase implements IDisposable {
|
|||
return this.privRecognizerConfig.recognitionMode;
|
||||
}
|
||||
|
||||
protected recognizeOverride: (recoMode: RecognitionMode, sc: (e: SpeechRecognitionResult) => void, ec: (e: string) => void) => any = undefined;
|
||||
protected recognizeOverride: (recoMode: RecognitionMode, sc: (e: SpeechRecognitionResult) => void, ec: (e: string) => void) => Promise<void> = undefined;
|
||||
|
||||
public async recognize(
|
||||
recoMode: RecognitionMode,
|
||||
|
@ -198,10 +198,11 @@ export abstract class ServiceRecognizerBase implements IDisposable {
|
|||
): Promise<void> {
|
||||
|
||||
if (this.recognizeOverride !== undefined) {
|
||||
return this.recognizeOverride(recoMode, successCallback, errorCallBack);
|
||||
await this.recognizeOverride(recoMode, successCallback, errorCallBack);
|
||||
return;
|
||||
}
|
||||
// Clear the existing configuration promise to force a re-transmission of config and context.
|
||||
this.privConnectionConfigurationPromise = null;
|
||||
this.privConnectionConfigurationPromise = undefined;
|
||||
this.privRecognizerConfig.recognitionMode = recoMode;
|
||||
|
||||
this.privSuccessCallback = successCallback;
|
||||
|
@ -232,7 +233,7 @@ export abstract class ServiceRecognizerBase implements IDisposable {
|
|||
try {
|
||||
await conPromise;
|
||||
} catch (error) {
|
||||
await this.cancelRecognitionLocal(CancellationReason.Error, CancellationErrorCode.ConnectionFailure, error);
|
||||
await this.cancelRecognitionLocal(CancellationReason.Error, CancellationErrorCode.ConnectionFailure, error as string);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -242,10 +243,10 @@ export abstract class ServiceRecognizerBase implements IDisposable {
|
|||
this.privRecognizer.sessionStarted(this.privRecognizer, sessionStartEventArgs);
|
||||
}
|
||||
|
||||
const messageRetrievalPromise = this.receiveMessage();
|
||||
void this.receiveMessage();
|
||||
const audioSendPromise = this.sendAudio(audioNode);
|
||||
|
||||
audioSendPromise.catch(async (error: string) => {
|
||||
audioSendPromise.catch(async (error: string): Promise<void> => {
|
||||
await this.cancelRecognitionLocal(CancellationReason.Error, CancellationErrorCode.RuntimeError, error);
|
||||
});
|
||||
|
||||
|
@ -272,7 +273,7 @@ export abstract class ServiceRecognizerBase implements IDisposable {
|
|||
}
|
||||
|
||||
public connectAsync(cb?: Callback, err?: Callback): void {
|
||||
this.connectImpl().then((connection: IConnection): void => {
|
||||
this.connectImpl().then((): void => {
|
||||
try {
|
||||
if (!!cb) {
|
||||
cb();
|
||||
|
@ -287,7 +288,7 @@ export abstract class ServiceRecognizerBase implements IDisposable {
|
|||
if (!!err) {
|
||||
err(reason);
|
||||
}
|
||||
/* tslint:disable:no-empty */
|
||||
/* eslint-disable no-empty */
|
||||
} catch (error) {
|
||||
}
|
||||
});
|
||||
|
@ -304,13 +305,14 @@ export abstract class ServiceRecognizerBase implements IDisposable {
|
|||
await this.disconnectOverride();
|
||||
}
|
||||
|
||||
try {
|
||||
await (await this.privConnectionPromise).dispose();
|
||||
} catch (error) {
|
||||
if (this.privConnectionPromise !== undefined) {
|
||||
try {
|
||||
await (await this.privConnectionPromise).dispose();
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
this.privConnectionPromise = null;
|
||||
this.privConnectionPromise = undefined;
|
||||
}
|
||||
|
||||
// Called when telemetry data is sent to the service.
|
||||
|
@ -318,7 +320,10 @@ export abstract class ServiceRecognizerBase implements IDisposable {
|
|||
public static telemetryData: (json: string) => void;
|
||||
public static telemetryDataEnabled: boolean = true;
|
||||
|
||||
public sendMessage(message: string): void { }
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
public sendMessage(message: string): Promise<void> {
|
||||
return;
|
||||
}
|
||||
|
||||
public async sendNetworkMessage(path: string, payload: string | ArrayBuffer): Promise<void> {
|
||||
const type: MessageType = typeof payload === "string" ? MessageType.Text : MessageType.Binary;
|
||||
|
@ -328,8 +333,13 @@ export abstract class ServiceRecognizerBase implements IDisposable {
|
|||
return connection.send(new SpeechConnectionMessage(type, path, this.privRequestSession.requestId, contentType, payload));
|
||||
}
|
||||
|
||||
public set activityTemplate(messagePayload: string) { this.privActivityTemplate = messagePayload; }
|
||||
public get activityTemplate(): string { return this.privActivityTemplate; }
|
||||
public set activityTemplate(messagePayload: string) {
|
||||
this.privActivityTemplate = messagePayload;
|
||||
}
|
||||
|
||||
public get activityTemplate(): string {
|
||||
return this.privActivityTemplate;
|
||||
}
|
||||
|
||||
protected abstract processTypeSpecificMessages(
|
||||
connectionMessage: SpeechConnectionMessage,
|
||||
|
@ -347,7 +357,7 @@ export abstract class ServiceRecognizerBase implements IDisposable {
|
|||
if (!!ServiceRecognizerBase.telemetryData) {
|
||||
try {
|
||||
ServiceRecognizerBase.telemetryData(telemetryData);
|
||||
/* tslint:disable:no-empty */
|
||||
/* eslint-disable no-empty */
|
||||
} catch { }
|
||||
}
|
||||
|
||||
|
@ -483,7 +493,7 @@ export abstract class ServiceRecognizerBase implements IDisposable {
|
|||
}
|
||||
}
|
||||
|
||||
protected sendSpeechContext = (connection: IConnection): Promise<void> => {
|
||||
protected sendSpeechContext(connection: IConnection): Promise<void> {
|
||||
const speechContextJson = this.speechContext.toJSON();
|
||||
this.privRequestSession.onSpeechContext();
|
||||
|
||||
|
@ -527,18 +537,18 @@ export abstract class ServiceRecognizerBase implements IDisposable {
|
|||
|
||||
// Establishes a websocket connection to the end point.
|
||||
protected connectImpl(): Promise<IConnection> {
|
||||
if (this.privConnectionPromise) {
|
||||
if (this.privConnectionPromise !== undefined) {
|
||||
return this.privConnectionPromise.then((connection: IConnection): Promise<IConnection> => {
|
||||
if (connection.state() === ConnectionState.Disconnected) {
|
||||
this.privConnectionId = null;
|
||||
this.privConnectionPromise = null;
|
||||
this.privConnectionPromise = undefined;
|
||||
this.privServiceHasSentMessage = false;
|
||||
return this.connectImpl();
|
||||
}
|
||||
return this.privConnectionPromise;
|
||||
}, (error: string): Promise<IConnection> => {
|
||||
}, (): Promise<IConnection> => {
|
||||
this.privConnectionId = null;
|
||||
this.privConnectionPromise = null;
|
||||
this.privConnectionPromise = undefined;
|
||||
this.privServiceHasSentMessage = false;
|
||||
return this.connectImpl();
|
||||
});
|
||||
|
@ -548,7 +558,8 @@ export abstract class ServiceRecognizerBase implements IDisposable {
|
|||
|
||||
// Attach an empty handler to allow the promise to run in the background while
|
||||
// other startup events happen. It'll eventually be awaited on.
|
||||
this.privConnectionPromise.catch(() => { });
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
this.privConnectionPromise.catch((): void => { });
|
||||
|
||||
if (this.postConnectImplOverride !== undefined) {
|
||||
return this.postConnectImplOverride(this.privConnectionPromise);
|
||||
|
@ -559,10 +570,10 @@ export abstract class ServiceRecognizerBase implements IDisposable {
|
|||
|
||||
protected configConnectionOverride: (connection: IConnection) => Promise<IConnection> = undefined;
|
||||
|
||||
protected sendSpeechServiceConfig = (connection: IConnection, requestSession: RequestSession, SpeechServiceConfigJson: string): Promise<void> => {
|
||||
protected sendSpeechServiceConfig(connection: IConnection, requestSession: RequestSession, SpeechServiceConfigJson: string): Promise<void> {
|
||||
// filter out anything that is not required for the service to work.
|
||||
if (ServiceRecognizerBase.telemetryDataEnabled !== true) {
|
||||
const withTelemetry = JSON.parse(SpeechServiceConfigJson);
|
||||
const withTelemetry: { context: { system: string } } = JSON.parse(SpeechServiceConfigJson) as { context: { system: string } } ;
|
||||
|
||||
const replacement: any = {
|
||||
context: {
|
||||
|
@ -574,7 +585,7 @@ export abstract class ServiceRecognizerBase implements IDisposable {
|
|||
}
|
||||
|
||||
if (this.privRecognizerConfig.parameters.getProperty("TranscriptionService_SingleChannel", "false").toLowerCase() === "true") {
|
||||
const json: { context: any } = JSON.parse(SpeechServiceConfigJson);
|
||||
const json: { context: { DisableReferenceChannel: string; MicSpec: string } } = JSON.parse(SpeechServiceConfigJson) as { context: { DisableReferenceChannel: string; MicSpec: string } } ;
|
||||
json.context.DisableReferenceChannel = "True";
|
||||
json.context.MicSpec = "1_0_0";
|
||||
SpeechServiceConfigJson = JSON.stringify(json);
|
||||
|
@ -593,18 +604,18 @@ export abstract class ServiceRecognizerBase implements IDisposable {
|
|||
}
|
||||
|
||||
protected async fetchConnection(): Promise<IConnection> {
|
||||
if (this.privConnectionConfigurationPromise) {
|
||||
if (this.privConnectionConfigurationPromise !== undefined) {
|
||||
return this.privConnectionConfigurationPromise.then((connection: IConnection): Promise<IConnection> => {
|
||||
if (connection.state() === ConnectionState.Disconnected) {
|
||||
this.privConnectionId = null;
|
||||
this.privConnectionConfigurationPromise = null;
|
||||
this.privConnectionConfigurationPromise = undefined;
|
||||
this.privServiceHasSentMessage = false;
|
||||
return this.fetchConnection();
|
||||
}
|
||||
return this.privConnectionConfigurationPromise;
|
||||
}, (error: string): Promise<IConnection> => {
|
||||
}, (): Promise<IConnection> => {
|
||||
this.privConnectionId = null;
|
||||
this.privConnectionConfigurationPromise = null;
|
||||
this.privConnectionConfigurationPromise = undefined;
|
||||
this.privServiceHasSentMessage = false;
|
||||
return this.fetchConnection();
|
||||
});
|
||||
|
@ -673,8 +684,9 @@ export abstract class ServiceRecognizerBase implements IDisposable {
|
|||
this.privRequestSession.recogNumber === startRecogNumber) {
|
||||
connection.send(
|
||||
new SpeechConnectionMessage(MessageType.Binary, "audio", this.privRequestSession.requestId, null, payload)
|
||||
).catch(() => {
|
||||
this.privRequestSession.onServiceTurnEndResponse(this.privRecognizerConfig.isContinuousRecognition).catch(() => { });
|
||||
).catch((): void => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
this.privRequestSession.onServiceTurnEndResponse(this.privRecognizerConfig.isContinuousRecognition).catch((): void => { });
|
||||
});
|
||||
|
||||
if (!audioStreamChunk?.isEnd) {
|
||||
|
@ -724,7 +736,7 @@ export abstract class ServiceRecognizerBase implements IDisposable {
|
|||
|
||||
// Attach to the underlying event. No need to hold onto the detach pointers as in the event the connection goes away,
|
||||
// it'll stop sending events.
|
||||
connection.events.attach((event: ConnectionEvent) => {
|
||||
connection.events.attach((event: ConnectionEvent): void => {
|
||||
this.connectionEvents.onEvent(event);
|
||||
});
|
||||
|
||||
|
@ -748,9 +760,7 @@ export abstract class ServiceRecognizerBase implements IDisposable {
|
|||
}
|
||||
|
||||
private delay(delayMs: number): Promise<void> {
|
||||
return new Promise((resolve: () => void, reject: (error: string) => void) => {
|
||||
this.privSetTimeout(resolve, delayMs);
|
||||
});
|
||||
return new Promise((resolve: () => void): number => this.privSetTimeout(resolve, delayMs));
|
||||
}
|
||||
|
||||
private writeBufferToConsole(buffer: ArrayBuffer): void {
|
||||
|
@ -759,12 +769,12 @@ export abstract class ServiceRecognizerBase implements IDisposable {
|
|||
out += "null";
|
||||
} else {
|
||||
const readView: Uint8Array = new Uint8Array(buffer);
|
||||
out += buffer.byteLength + "\r\n";
|
||||
out += `${buffer.byteLength}\r\n`;
|
||||
for (let i: number = 0; i < buffer.byteLength; i++) {
|
||||
out += readView[i].toString(16).padStart(2, "0") + " ";
|
||||
}
|
||||
}
|
||||
// tslint:disable-next-line:no-console
|
||||
// eslint-disable-next-line no-console
|
||||
console.info(out);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// tslint:disable:max-classes-per-file
|
||||
/* eslint-disable max-classes-per-file */
|
||||
|
||||
import {
|
||||
AudioSourceErrorEvent,
|
||||
|
@ -54,7 +54,7 @@ export class ServiceTelemetryListener implements IEventListener<PlatformEvent> {
|
|||
private privPhraseLatencies: number[];
|
||||
private privHypothesisLatencies: number[];
|
||||
|
||||
constructor(requestId: string, audioSourceId: string, audioNodeId: string) {
|
||||
public constructor(requestId: string, audioSourceId: string, audioNodeId: string) {
|
||||
this.privRequestId = requestId;
|
||||
this.privAudioSourceId = audioSourceId;
|
||||
this.privAudioNodeId = audioNodeId;
|
||||
|
@ -76,7 +76,7 @@ export class ServiceTelemetryListener implements IEventListener<PlatformEvent> {
|
|||
}
|
||||
}
|
||||
|
||||
public onEvent = (e: PlatformEvent): void => {
|
||||
public onEvent(e: PlatformEvent): void {
|
||||
if (this.privIsDisposed) {
|
||||
return;
|
||||
}
|
||||
|
@ -173,7 +173,7 @@ export class ServiceTelemetryListener implements IEventListener<PlatformEvent> {
|
|||
}
|
||||
}
|
||||
|
||||
public getTelemetry = (): string => {
|
||||
public getTelemetry(): string {
|
||||
const metrics = new Array<IMetric>();
|
||||
|
||||
if (this.privListeningTriggerMetric) {
|
||||
|
@ -227,11 +227,11 @@ export class ServiceTelemetryListener implements IEventListener<PlatformEvent> {
|
|||
this.privHypothesisLatencies.length !== 0);
|
||||
}
|
||||
|
||||
public dispose = (): void => {
|
||||
public dispose(): void {
|
||||
this.privIsDisposed = true;
|
||||
}
|
||||
|
||||
private getConnectionError = (statusCode: number): string => {
|
||||
private getConnectionError(statusCode: number): string {
|
||||
/*
|
||||
-- Websocket status codes --
|
||||
NormalClosure = 1000,
|
||||
|
|
|
@ -55,7 +55,7 @@ export class SpeakerIdMessageAdapter {
|
|||
Promise<IRestResponse> {
|
||||
|
||||
const uri = this.getOperationUri(profileType);
|
||||
return this.privRestAdapter.request(RestRequestType.Post, uri, this.getQueryParams(), { locale: lang });
|
||||
return this.privRestAdapter.request(RestRequestType.Post, uri, this.getQueryParams({}), { locale: lang });
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -70,9 +70,8 @@ export class SpeakerIdMessageAdapter {
|
|||
Promise<IRestResponse> {
|
||||
|
||||
const uri = this.getOperationUri(profile.profileType) + "/" + profile.profileId + "/enrollments";
|
||||
return audioSource.blob.then<IRestResponse>((result: Blob | Buffer): Promise<IRestResponse> => {
|
||||
return this.privRestAdapter.request(RestRequestType.File, uri, this.getQueryParams({ ignoreMinLength: "true" }), null, result);
|
||||
});
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||
return audioSource.blob.then<IRestResponse>((result: Blob | Buffer): Promise<IRestResponse> => this.privRestAdapter.request(RestRequestType.File, uri, this.getQueryParams({ ignoreMinLength: "true" }), null, result));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -91,7 +90,7 @@ export class SpeakerIdMessageAdapter {
|
|||
const result: Blob | Buffer = await audioSource.blob;
|
||||
return this.privRestAdapter.request(RestRequestType.File, uri, this.getQueryParams({ ignoreMinLength: "true" }), null, result);
|
||||
} catch (e) {
|
||||
return Promise.resolve({ data: e } as IRestResponse);
|
||||
return Promise.resolve({ data: e as string } as IRestResponse);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,7 +110,7 @@ export class SpeakerIdMessageAdapter {
|
|||
const result: Blob | Buffer = await audioSource.blob;
|
||||
return this.privRestAdapter.request(RestRequestType.File, uri, this.getQueryParams({ profileIds: model.voiceProfileIds, ignoreMinLength: "true" }), null, result);
|
||||
} catch (e) {
|
||||
return Promise.resolve({ data: e } as IRestResponse);
|
||||
return Promise.resolve({ data: e as string } as IRestResponse);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -149,7 +148,7 @@ export class SpeakerIdMessageAdapter {
|
|||
* @returns {Promise<IRestResponse>} promised rest response containing list of valid phrases
|
||||
*/
|
||||
public getPhrases(profileType: VoiceProfileType, lang: string): Promise<IRestResponse> {
|
||||
const uri = `${this.getOperationUri(profileType)}`.replace(`profiles`, `phrases`) + "/" + lang;
|
||||
const uri = `${this.getOperationUri(profileType)}`.replace("profiles", "phrases") + "/" + lang;
|
||||
return this.privRestAdapter.request(RestRequestType.Get, uri, this.getQueryParams());
|
||||
}
|
||||
|
||||
|
@ -186,7 +185,7 @@ export class SpeakerIdMessageAdapter {
|
|||
return this.privUri.replace("{mode}", mode).replace("{dependency}", dependency);
|
||||
}
|
||||
|
||||
private getQueryParams(params: any = {}): any {
|
||||
private getQueryParams(params: { [key: string]: any } = {}): { [key: string]: any } {
|
||||
|
||||
params[RestConfigBase.configParams.apiVersion] = this.privApiVersion;
|
||||
return params;
|
||||
|
|
|
@ -8,7 +8,7 @@ export class SpeakerRecognitionConfig {
|
|||
private privParameters: PropertyCollection;
|
||||
private privContext: Context;
|
||||
|
||||
constructor(
|
||||
public constructor(
|
||||
context: Context,
|
||||
parameters: PropertyCollection) {
|
||||
this.privContext = context ? context : new Context(null);
|
||||
|
|
|
@ -38,10 +38,10 @@ export class SpeechConnectionFactory extends ConnectionFactoryBase {
|
|||
private readonly dictationRelativeUri: string = "/speech/recognition/dictation/cognitiveservices/v1";
|
||||
private readonly universalUri: string = "/speech/universal/v";
|
||||
|
||||
public create = (
|
||||
public create(
|
||||
config: RecognizerConfig,
|
||||
authInfo: AuthInfo,
|
||||
connectionId?: string): IConnection => {
|
||||
connectionId?: string): IConnection {
|
||||
|
||||
let endpoint: string = config.parameters.getProperty(PropertyId.SpeechServiceConnection_Endpoint, undefined);
|
||||
const region: string = config.parameters.getProperty(PropertyId.SpeechServiceConnection_Region, undefined);
|
||||
|
|
|
@ -84,11 +84,11 @@ export class SpeechConnectionMessage extends ConnectionMessage {
|
|||
return this.privAdditionalHeaders;
|
||||
}
|
||||
|
||||
public static fromConnectionMessage = (message: ConnectionMessage): SpeechConnectionMessage => {
|
||||
public static fromConnectionMessage(message: ConnectionMessage): SpeechConnectionMessage {
|
||||
let path = null;
|
||||
let requestId = null;
|
||||
let contentType = null;
|
||||
let requestTimestamp = null;
|
||||
// let requestTimestamp = null;
|
||||
let streamId = null;
|
||||
const additionalHeaders: IStringDictionary<string> = {};
|
||||
|
||||
|
@ -99,8 +99,8 @@ export class SpeechConnectionMessage extends ConnectionMessage {
|
|||
path = message.headers[headerName];
|
||||
} else if (headerName.toLowerCase() === HeaderNames.RequestId.toLowerCase()) {
|
||||
requestId = message.headers[headerName];
|
||||
} else if (headerName.toLowerCase() === HeaderNames.RequestTimestamp.toLowerCase()) {
|
||||
requestTimestamp = message.headers[headerName];
|
||||
// } else if (headerName.toLowerCase() === HeaderNames.RequestTimestamp.toLowerCase()) {
|
||||
// requestTimestamp = message.headers[headerName];
|
||||
} else if (headerName.toLowerCase() === HeaderNames.ContentType.toLowerCase()) {
|
||||
contentType = message.headers[headerName];
|
||||
} else if (headerName.toLowerCase() === HeaderNames.RequestStreamId.toLowerCase()) {
|
||||
|
|
|
@ -6,15 +6,33 @@ import {
|
|||
IDynamicGrammar,
|
||||
} from "./Exports";
|
||||
|
||||
interface Context {
|
||||
[section: string]: any;
|
||||
}
|
||||
|
||||
interface PhraseContext {
|
||||
[section: string]: any;
|
||||
phraseDetection?: {
|
||||
enrichment?: {
|
||||
pronunciationAssessment: any;
|
||||
};
|
||||
};
|
||||
phraseOutput?: {
|
||||
detailed?: {
|
||||
options?: string[];
|
||||
};
|
||||
format?: any;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Represents the JSON used in the speech.context message sent to the speech service.
|
||||
* The dynamic grammar is always refreshed from the encapsulated dynamic grammar object.
|
||||
*/
|
||||
export class SpeechContext {
|
||||
private privContext: { [section: string]: any } = {};
|
||||
private privContext: PhraseContext = {};
|
||||
private privDynamicGrammar: DynamicGrammarBuilder;
|
||||
|
||||
constructor(dynamicGrammar: DynamicGrammarBuilder) {
|
||||
public constructor(dynamicGrammar: DynamicGrammarBuilder) {
|
||||
this.privDynamicGrammar = dynamicGrammar;
|
||||
}
|
||||
|
||||
|
@ -23,7 +41,7 @@ export class SpeechContext {
|
|||
* @param sectionName Name of the section to add.
|
||||
* @param value JSON serializable object that represents the value.
|
||||
*/
|
||||
public setSection(sectionName: string, value: any): void {
|
||||
public setSection(sectionName: string, value: string | Context): void {
|
||||
this.privContext[sectionName] = value;
|
||||
}
|
||||
|
||||
|
@ -40,7 +58,7 @@ export class SpeechContext {
|
|||
}
|
||||
};
|
||||
}
|
||||
this.privContext.phraseDetection.enrichment.pronunciationAssessment = JSON.parse(params);
|
||||
this.privContext.phraseDetection.enrichment.pronunciationAssessment = JSON.parse(params) as Context;
|
||||
if (this.privContext.phraseOutput === undefined) {
|
||||
this.privContext.phraseOutput = {
|
||||
detailed: {
|
||||
|
|
|
@ -29,7 +29,7 @@ import { IConnectionFactory } from "./IConnectionFactory";
|
|||
import { RecognizerConfig } from "./RecognizerConfig";
|
||||
import { SpeechConnectionMessage } from "./SpeechConnectionMessage.Internal";
|
||||
|
||||
// tslint:disable-next-line:max-classes-per-file
|
||||
// eslint-disable-next-line max-classes-per-file
|
||||
export class SpeechServiceRecognizer extends ServiceRecognizerBase {
|
||||
|
||||
private privSpeechRecognizer: SpeechRecognizer;
|
||||
|
@ -59,7 +59,7 @@ export class SpeechServiceRecognizer extends ServiceRecognizerBase {
|
|||
resultType: "Always"
|
||||
}
|
||||
});
|
||||
const customModels: { language: string, endpoint: string }[] = recognizerConfig.sourceLanguageModels;
|
||||
const customModels: { language: string; endpoint: string }[] = recognizerConfig.sourceLanguageModels;
|
||||
if (customModels !== undefined) {
|
||||
this.privSpeechContext.setSection("phraseDetection", {
|
||||
customModels,
|
||||
|
@ -103,7 +103,7 @@ export class SpeechServiceRecognizer extends ServiceRecognizerBase {
|
|||
if (!!this.privSpeechRecognizer.recognizing) {
|
||||
try {
|
||||
this.privSpeechRecognizer.recognizing(this.privSpeechRecognizer, ev);
|
||||
/* tslint:disable:no-empty */
|
||||
/* eslint-disable no-empty */
|
||||
} catch (error) {
|
||||
// Not going to let errors in the event handler
|
||||
// trip things up.
|
||||
|
@ -165,7 +165,7 @@ export class SpeechServiceRecognizer extends ServiceRecognizerBase {
|
|||
if (!!this.privSpeechRecognizer.recognized) {
|
||||
try {
|
||||
this.privSpeechRecognizer.recognized(this.privSpeechRecognizer, event);
|
||||
/* tslint:disable:no-empty */
|
||||
/* eslint-disable no-empty */
|
||||
} catch (error) {
|
||||
// Not going to let errors in the event handler
|
||||
// trip things up.
|
||||
|
@ -178,7 +178,7 @@ export class SpeechServiceRecognizer extends ServiceRecognizerBase {
|
|||
this.privSuccessCallback(result);
|
||||
} catch (e) {
|
||||
if (!!this.privErrorCallback) {
|
||||
this.privErrorCallback(e);
|
||||
this.privErrorCallback(e as string);
|
||||
}
|
||||
}
|
||||
// Only invoke the call back once.
|
||||
|
@ -216,7 +216,7 @@ export class SpeechServiceRecognizer extends ServiceRecognizerBase {
|
|||
sessionId);
|
||||
try {
|
||||
this.privSpeechRecognizer.canceled(this.privSpeechRecognizer, cancelEvent);
|
||||
/* tslint:disable:no-empty */
|
||||
/* eslint-disable no-empty */
|
||||
} catch { }
|
||||
}
|
||||
|
||||
|
@ -236,7 +236,7 @@ export class SpeechServiceRecognizer extends ServiceRecognizerBase {
|
|||
try {
|
||||
this.privSuccessCallback(result);
|
||||
this.privSuccessCallback = undefined;
|
||||
/* tslint:disable:no-empty */
|
||||
/* eslint-disable no-empty */
|
||||
} catch { }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
import {
|
||||
ProxyInfo,
|
||||
WebsocketConnection, WebsocketMessageAdapter,
|
||||
WebsocketConnection
|
||||
} from "../common.browser/Exports";
|
||||
import {
|
||||
IConnection,
|
||||
|
@ -26,10 +26,10 @@ export class SpeechSynthesisConnectionFactory implements ISynthesisConnectionFac
|
|||
|
||||
private readonly synthesisUri: string = "/cognitiveservices/websocket/v1";
|
||||
|
||||
public create = (
|
||||
public create(
|
||||
config: SynthesizerConfig,
|
||||
authInfo: AuthInfo,
|
||||
connectionId?: string): IConnection => {
|
||||
connectionId?: string): IConnection {
|
||||
|
||||
let endpoint: string = config.parameters.getProperty(PropertyId.SpeechServiceConnection_Endpoint, undefined);
|
||||
const region: string = config.parameters.getProperty(PropertyId.SpeechServiceConnection_Region, undefined);
|
||||
|
|
|
@ -66,21 +66,25 @@ export class SynthesisAdapterBase implements IDisposable {
|
|||
return this.privServiceEvents;
|
||||
}
|
||||
|
||||
protected speakOverride: (ssml: string, requestId: string, sc: (e: SpeechSynthesisResult) => void, ec: (e: string) => void) => any = undefined;
|
||||
protected speakOverride: (ssml: string, requestId: string, sc: (e: SpeechSynthesisResult) => void, ec: (e: string) => void) => void = undefined;
|
||||
|
||||
// Called when telemetry data is sent to the service.
|
||||
// Used for testing Telemetry capture.
|
||||
public static telemetryData: (json: string) => void;
|
||||
public static telemetryDataEnabled: boolean = true;
|
||||
|
||||
public set activityTemplate(messagePayload: string) { this.privActivityTemplate = messagePayload; }
|
||||
public get activityTemplate(): string { return this.privActivityTemplate; }
|
||||
public set activityTemplate(messagePayload: string) {
|
||||
this.privActivityTemplate = messagePayload;
|
||||
}
|
||||
public get activityTemplate(): string {
|
||||
return this.privActivityTemplate;
|
||||
}
|
||||
|
||||
protected receiveMessageOverride: () => any = undefined;
|
||||
protected receiveMessageOverride: () => void = undefined;
|
||||
|
||||
protected connectImplOverride: (isUnAuthorized: boolean) => any = undefined;
|
||||
protected connectImplOverride: (isUnAuthorized: boolean) => void = undefined;
|
||||
|
||||
protected configConnectionOverride: (connection: IConnection) => any = undefined;
|
||||
protected configConnectionOverride: (connection: IConnection) => Promise<IConnection> = undefined;
|
||||
|
||||
public set audioOutputFormat(format: AudioOutputFormatImpl) {
|
||||
this.privAudioOutputFormat = format;
|
||||
|
@ -97,7 +101,7 @@ export class SynthesisAdapterBase implements IDisposable {
|
|||
|
||||
// A promise for a configured connection.
|
||||
// Do not consume directly, call fetchConnection instead.
|
||||
private privConnectionConfigurationPromise: Promise<IConnection>;
|
||||
private privConnectionConfigurationPromise: Promise<IConnection> = undefined;
|
||||
|
||||
// A promise for a connection, but one that has not had the speech context sent yet.
|
||||
// Do not consume directly, call fetchConnection instead.
|
||||
|
@ -108,7 +112,6 @@ export class SynthesisAdapterBase implements IDisposable {
|
|||
private privServiceEvents: EventSource<ServiceEvent>;
|
||||
private privSynthesisContext: SynthesisContext;
|
||||
private privAgentConfig: AgentConfig;
|
||||
private privServiceHasSentMessage: boolean;
|
||||
private privActivityTemplate: string;
|
||||
private privAudioOutputFormat: AudioOutputFormatImpl;
|
||||
private privSessionAudioDestination: IAudioDestination;
|
||||
|
@ -150,7 +153,7 @@ export class SynthesisAdapterBase implements IDisposable {
|
|||
if (connectionClosedEvent.statusCode !== 1000) {
|
||||
this.cancelSynthesisLocal(CancellationReason.Error,
|
||||
connectionClosedEvent.statusCode === 1007 ? CancellationErrorCode.BadRequestParameters : CancellationErrorCode.ConnectionFailure,
|
||||
connectionClosedEvent.reason + " websocket error code: " + connectionClosedEvent.statusCode);
|
||||
`${connectionClosedEvent.reason} websocket error code: ${connectionClosedEvent.statusCode}`);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -176,7 +179,7 @@ export class SynthesisAdapterBase implements IDisposable {
|
|||
if (this.privSessionAudioDestination !== undefined) {
|
||||
this.privSessionAudioDestination.close();
|
||||
}
|
||||
if (this.privConnectionConfigurationPromise) {
|
||||
if (this.privConnectionConfigurationPromise !== undefined) {
|
||||
const connection: IConnection = await this.privConnectionConfigurationPromise;
|
||||
await connection.dispose(reason);
|
||||
}
|
||||
|
@ -236,9 +239,9 @@ export class SynthesisAdapterBase implements IDisposable {
|
|||
this.privSpeechSynthesizer.synthesisStarted(this.privSpeechSynthesizer, synthesisStartEventArgs);
|
||||
}
|
||||
|
||||
const messageRetrievalPromise = this.receiveMessage();
|
||||
void this.receiveMessage();
|
||||
} catch (e) {
|
||||
this.cancelSynthesisLocal(CancellationReason.Error, CancellationErrorCode.ConnectionFailure, e);
|
||||
this.cancelSynthesisLocal(CancellationReason.Error, CancellationErrorCode.ConnectionFailure, e as string);
|
||||
return Promise.reject(e);
|
||||
}
|
||||
}
|
||||
|
@ -263,14 +266,14 @@ export class SynthesisAdapterBase implements IDisposable {
|
|||
const cancelEvent: SpeechSynthesisEventArgs = new SpeechSynthesisEventArgs(result);
|
||||
try {
|
||||
this.privSpeechSynthesizer.SynthesisCanceled(this.privSpeechSynthesizer, cancelEvent);
|
||||
/* tslint:disable:no-empty */
|
||||
/* eslint-disable no-empty */
|
||||
} catch { }
|
||||
}
|
||||
|
||||
if (!!this.privSuccessCallback) {
|
||||
try {
|
||||
this.privSuccessCallback(result);
|
||||
/* tslint:disable:no-empty */
|
||||
/* eslint-disable no-empty */
|
||||
} catch { }
|
||||
}
|
||||
}
|
||||
|
@ -292,10 +295,8 @@ export class SynthesisAdapterBase implements IDisposable {
|
|||
}
|
||||
}
|
||||
|
||||
protected processTypeSpecificMessages(
|
||||
connectionMessage: SpeechConnectionMessage,
|
||||
successCallback?: (e: SpeechSynthesisResult) => void,
|
||||
errorCallBack?: (e: string) => void): boolean {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
protected processTypeSpecificMessages(connectionMessage: SpeechConnectionMessage): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -321,7 +322,6 @@ export class SynthesisAdapterBase implements IDisposable {
|
|||
}
|
||||
}
|
||||
|
||||
this.privServiceHasSentMessage = true;
|
||||
|
||||
const connectionMessage = SpeechConnectionMessage.fromConnectionMessage(message);
|
||||
|
||||
|
@ -430,7 +430,7 @@ export class SynthesisAdapterBase implements IDisposable {
|
|||
}
|
||||
} catch (error) {
|
||||
if (!!this.privErrorCallback) {
|
||||
this.privErrorCallback(error);
|
||||
this.privErrorCallback(error as string);
|
||||
}
|
||||
}
|
||||
if (this.privSpeechSynthesizer.synthesisCompleted) {
|
||||
|
@ -465,7 +465,7 @@ export class SynthesisAdapterBase implements IDisposable {
|
|||
}
|
||||
}
|
||||
|
||||
protected sendSynthesisContext = (connection: IConnection): Promise<void> => {
|
||||
protected sendSynthesisContext(connection: IConnection): Promise<void> {
|
||||
const synthesisContextJson = this.synthesisContext.toJSON();
|
||||
|
||||
if (synthesisContextJson) {
|
||||
|
@ -480,61 +480,60 @@ export class SynthesisAdapterBase implements IDisposable {
|
|||
}
|
||||
|
||||
protected connectImpl(isUnAuthorized: boolean = false): Promise<IConnection> {
|
||||
if (this.privConnectionPromise) {
|
||||
if (this.privConnectionPromise != null) {
|
||||
return this.privConnectionPromise.then((connection: IConnection): Promise<IConnection> => {
|
||||
if (connection.state() === ConnectionState.Disconnected) {
|
||||
this.privConnectionId = null;
|
||||
this.privConnectionPromise = null;
|
||||
this.privServiceHasSentMessage = false;
|
||||
return this.connectImpl();
|
||||
}
|
||||
return this.privConnectionPromise;
|
||||
}, (error: string): Promise<IConnection> => {
|
||||
}, (): Promise<IConnection> => {
|
||||
this.privConnectionId = null;
|
||||
this.privConnectionPromise = null;
|
||||
this.privServiceHasSentMessage = false;
|
||||
return this.connectImpl();
|
||||
});
|
||||
}
|
||||
this.privAuthFetchEventId = createNoDashGuid();
|
||||
this.privConnectionId = createNoDashGuid();
|
||||
|
||||
this.privSynthesisTurn.onPreConnectionStart(this.privAuthFetchEventId, this.privConnectionId);
|
||||
this.privSynthesisTurn.onPreConnectionStart(this.privAuthFetchEventId);
|
||||
|
||||
const authPromise = isUnAuthorized ? this.privAuthentication.fetchOnExpiry(this.privAuthFetchEventId) : this.privAuthentication.fetch(this.privAuthFetchEventId);
|
||||
|
||||
this.privConnectionPromise = authPromise.then(async (result: AuthInfo) => {
|
||||
await this.privSynthesisTurn.onAuthCompleted(false);
|
||||
this.privConnectionPromise = authPromise.then(async (result: AuthInfo): Promise<IConnection> => {
|
||||
this.privSynthesisTurn.onAuthCompleted(false);
|
||||
|
||||
const connection: IConnection = this.privConnectionFactory.create(this.privSynthesizerConfig, result, this.privConnectionId);
|
||||
|
||||
// Attach to the underlying event. No need to hold onto the detach pointers as in the event the connection goes away,
|
||||
// it'll stop sending events.
|
||||
connection.events.attach((event: ConnectionEvent) => {
|
||||
connection.events.attach((event: ConnectionEvent): void => {
|
||||
this.connectionEvents.onEvent(event);
|
||||
});
|
||||
const response = await connection.open();
|
||||
if (response.statusCode === 200) {
|
||||
await this.privSynthesisTurn.onConnectionEstablishCompleted(response.statusCode);
|
||||
this.privSynthesisTurn.onConnectionEstablishCompleted(response.statusCode);
|
||||
return Promise.resolve(connection);
|
||||
} else if (response.statusCode === 403 && !isUnAuthorized) {
|
||||
return this.connectImpl(true);
|
||||
} else {
|
||||
await this.privSynthesisTurn.onConnectionEstablishCompleted(response.statusCode, response.reason);
|
||||
this.privSynthesisTurn.onConnectionEstablishCompleted(response.statusCode);
|
||||
return Promise.reject(`Unable to contact server. StatusCode: ${response.statusCode}, ${this.privSynthesizerConfig.parameters.getProperty(PropertyId.SpeechServiceConnection_Endpoint)} Reason: ${response.reason}`);
|
||||
}
|
||||
}, async (error: string): Promise<IConnection> => {
|
||||
await this.privSynthesisTurn.onAuthCompleted(true, error);
|
||||
}, (error: string): Promise<IConnection> => {
|
||||
this.privSynthesisTurn.onAuthCompleted(true);
|
||||
throw new Error(error);
|
||||
});
|
||||
|
||||
// Attach an empty handler to allow the promise to run in the background while
|
||||
// other startup events happen. It'll eventually be awaited on.
|
||||
this.privConnectionPromise.catch(() => { });
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
this.privConnectionPromise.catch((): void => { });
|
||||
|
||||
return this.privConnectionPromise;
|
||||
}
|
||||
protected sendSpeechServiceConfig = (connection: IConnection, SpeechServiceConfigJson: string): Promise<void> => {
|
||||
protected sendSpeechServiceConfig(connection: IConnection, SpeechServiceConfigJson: string): Promise<void> {
|
||||
if (SpeechServiceConfigJson) {
|
||||
return connection.send(new SpeechConnectionMessage(
|
||||
MessageType.Text,
|
||||
|
@ -545,7 +544,7 @@ export class SynthesisAdapterBase implements IDisposable {
|
|||
}
|
||||
}
|
||||
|
||||
protected sendSsmlMessage = (connection: IConnection, ssml: string, requestId: string): Promise<void> => {
|
||||
protected sendSsmlMessage(connection: IConnection, ssml: string, requestId: string): Promise<void> {
|
||||
return connection.send(new SpeechConnectionMessage(
|
||||
MessageType.Text,
|
||||
"ssml",
|
||||
|
@ -555,19 +554,17 @@ export class SynthesisAdapterBase implements IDisposable {
|
|||
}
|
||||
|
||||
private async fetchConnection(): Promise<IConnection> {
|
||||
if (this.privConnectionConfigurationPromise) {
|
||||
if (this.privConnectionConfigurationPromise !== undefined) {
|
||||
return this.privConnectionConfigurationPromise.then((connection: IConnection): Promise<IConnection> => {
|
||||
if (connection.state() === ConnectionState.Disconnected) {
|
||||
this.privConnectionId = null;
|
||||
this.privConnectionConfigurationPromise = null;
|
||||
this.privServiceHasSentMessage = false;
|
||||
this.privConnectionConfigurationPromise = undefined;
|
||||
return this.fetchConnection();
|
||||
}
|
||||
return this.privConnectionConfigurationPromise;
|
||||
}, (error: string): Promise<IConnection> => {
|
||||
}, (): Promise<IConnection> => {
|
||||
this.privConnectionId = null;
|
||||
this.privConnectionConfigurationPromise = null;
|
||||
this.privServiceHasSentMessage = false;
|
||||
this.privConnectionConfigurationPromise = undefined;
|
||||
return this.fetchConnection();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ export class SynthesisContext {
|
|||
private privSpeechSynthesizer: SpeechSynthesizer;
|
||||
private privAudioOutputFormat: AudioOutputFormatImpl;
|
||||
|
||||
constructor(speechSynthesizer: SpeechSynthesizer) {
|
||||
public constructor(speechSynthesizer: SpeechSynthesizer) {
|
||||
this.privSpeechSynthesizer = speechSynthesizer;
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ export class SynthesisContext {
|
|||
* @param sectionName Name of the section to add.
|
||||
* @param value JSON serializable object that represents the value.
|
||||
*/
|
||||
public setSection(sectionName: string, value: any): void {
|
||||
public setSection(sectionName: string, value: string | object): void {
|
||||
this.privContext[sectionName] = value;
|
||||
}
|
||||
|
||||
|
@ -62,15 +62,15 @@ export class SynthesisContext {
|
|||
|
||||
interface ISynthesisSection {
|
||||
audio: {
|
||||
outputFormat: string,
|
||||
outputFormat: string;
|
||||
metadataOptions: {
|
||||
bookmarkEnabled: boolean,
|
||||
wordBoundaryEnabled: boolean,
|
||||
visemeEnabled: boolean,
|
||||
sentenceBoundaryEnabled: boolean,
|
||||
}
|
||||
bookmarkEnabled: boolean;
|
||||
wordBoundaryEnabled: boolean;
|
||||
visemeEnabled: boolean;
|
||||
sentenceBoundaryEnabled: boolean;
|
||||
};
|
||||
};
|
||||
language: {
|
||||
autoDetection: boolean
|
||||
autoDetection: boolean;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// tslint:disable:max-classes-per-file
|
||||
/* eslint-disable max-classes-per-file */
|
||||
|
||||
import { EventType, PlatformEvent } from "../common/Exports";
|
||||
|
||||
export class SpeechSynthesisEvent extends PlatformEvent {
|
||||
private privRequestId: string;
|
||||
|
||||
constructor(eventName: string, requestId: string, eventType: EventType = EventType.Info) {
|
||||
public constructor(eventName: string, requestId: string, eventType: EventType = EventType.Info) {
|
||||
super(eventName, eventType);
|
||||
|
||||
this.privRequestId = requestId;
|
||||
|
@ -23,7 +23,7 @@ export class SynthesisTriggeredEvent extends SpeechSynthesisEvent {
|
|||
private privSessionAudioDestinationId: string;
|
||||
private privTurnAudioDestinationId: string;
|
||||
|
||||
constructor(requestId: string, sessionAudioDestinationId: string, turnAudioDestinationId: string) {
|
||||
public constructor(requestId: string, sessionAudioDestinationId: string, turnAudioDestinationId: string) {
|
||||
super("SynthesisTriggeredEvent", requestId);
|
||||
|
||||
this.privSessionAudioDestinationId = sessionAudioDestinationId;
|
||||
|
@ -42,7 +42,7 @@ export class SynthesisTriggeredEvent extends SpeechSynthesisEvent {
|
|||
export class ConnectingToSynthesisServiceEvent extends SpeechSynthesisEvent {
|
||||
private privAuthFetchEventId: string;
|
||||
|
||||
constructor(requestId: string, authFetchEventId: string) {
|
||||
public constructor(requestId: string, authFetchEventId: string) {
|
||||
super("ConnectingToSynthesisServiceEvent", requestId);
|
||||
this.privAuthFetchEventId = authFetchEventId;
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ export class ConnectingToSynthesisServiceEvent extends SpeechSynthesisEvent {
|
|||
export class SynthesisStartedEvent extends SpeechSynthesisEvent {
|
||||
private privAuthFetchEventId: string;
|
||||
|
||||
constructor(requestId: string, authFetchEventId: string) {
|
||||
public constructor(requestId: string, authFetchEventId: string) {
|
||||
super("SynthesisStartedEvent", requestId);
|
||||
|
||||
this.privAuthFetchEventId = authFetchEventId;
|
||||
|
|
|
@ -94,7 +94,7 @@ export class SynthesisTurn {
|
|||
private privIsSSML: boolean;
|
||||
private privTurnAudioDestination: IAudioDestination;
|
||||
|
||||
constructor() {
|
||||
public constructor() {
|
||||
this.privRequestId = createNoDashGuid();
|
||||
this.privTurnDeferral = new Deferred<void>();
|
||||
|
||||
|
@ -150,18 +150,18 @@ export class SynthesisTurn {
|
|||
this.onEvent(new SynthesisTriggeredEvent(this.requestId, undefined, audioDestination === undefined ? undefined : audioDestination.id()));
|
||||
}
|
||||
|
||||
public onPreConnectionStart = (authFetchEventId: string, connectionId: string): void => {
|
||||
public onPreConnectionStart(authFetchEventId: string): void {
|
||||
this.privAuthFetchEventId = authFetchEventId;
|
||||
this.onEvent(new ConnectingToSynthesisServiceEvent(this.privRequestId, this.privAuthFetchEventId));
|
||||
}
|
||||
|
||||
public onAuthCompleted = (isError: boolean, error?: string): void => {
|
||||
public onAuthCompleted(isError: boolean): void {
|
||||
if (isError) {
|
||||
this.onComplete();
|
||||
}
|
||||
}
|
||||
|
||||
public onConnectionEstablishCompleted = (statusCode: number, reason?: string): void => {
|
||||
public onConnectionEstablishCompleted(statusCode: number): void {
|
||||
if (statusCode === 200) {
|
||||
this.onEvent(new SynthesisStartedEvent(this.requestId, this.privAuthFetchEventId));
|
||||
this.privBytesReceived = 0;
|
||||
|
@ -171,24 +171,24 @@ export class SynthesisTurn {
|
|||
}
|
||||
}
|
||||
|
||||
public onServiceResponseMessage = (responseJson: string): void => {
|
||||
const response: ISynthesisResponse = JSON.parse(responseJson);
|
||||
public onServiceResponseMessage(responseJson: string): void {
|
||||
const response: ISynthesisResponse = JSON.parse(responseJson) as ISynthesisResponse;
|
||||
this.streamId = response.audio.streamId;
|
||||
}
|
||||
|
||||
public onServiceTurnEndResponse = (): void => {
|
||||
public onServiceTurnEndResponse(): void {
|
||||
this.privInTurn = false;
|
||||
this.privTurnDeferral.resolve();
|
||||
this.onComplete();
|
||||
}
|
||||
|
||||
public onServiceTurnStartResponse = (): void => {
|
||||
public onServiceTurnStartResponse(): void {
|
||||
if (!!this.privTurnDeferral && !!this.privInTurn) {
|
||||
// What? How are we starting a turn with another not done?
|
||||
this.privTurnDeferral.reject("Another turn started before current completed.");
|
||||
// Avoid UnhandledPromiseRejection if privTurnDeferral is not being awaited
|
||||
/* tslint:disable:no-empty */
|
||||
this.privTurnDeferral.promise.then().catch(() => { });
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
this.privTurnDeferral.promise.then().catch((): void => { });
|
||||
}
|
||||
this.privInTurn = true;
|
||||
this.privTurnDeferral = new Deferred<void>();
|
||||
|
@ -214,7 +214,7 @@ export class SynthesisTurn {
|
|||
}
|
||||
}
|
||||
|
||||
public dispose = (error?: string): void => {
|
||||
public dispose(): void {
|
||||
if (!this.privIsDisposed) {
|
||||
// we should have completed by now. If we did not its an unknown error.
|
||||
this.privIsDisposed = true;
|
||||
|
@ -235,7 +235,7 @@ export class SynthesisTurn {
|
|||
return animation;
|
||||
}
|
||||
|
||||
protected onEvent = (event: SpeechSynthesisEvent): void => {
|
||||
protected onEvent(event: SpeechSynthesisEvent): void {
|
||||
Events.instance.onEvent(event);
|
||||
}
|
||||
|
||||
|
@ -253,7 +253,7 @@ export class SynthesisTurn {
|
|||
}
|
||||
}
|
||||
|
||||
private onComplete = (): void => {
|
||||
private onComplete(): void {
|
||||
if (this.privIsSynthesizing) {
|
||||
this.privIsSynthesizing = false;
|
||||
this.privIsSynthesisEnded = true;
|
||||
|
|
|
@ -14,7 +14,7 @@ export class SynthesizerConfig {
|
|||
private privSpeechServiceConfig: SpeechServiceConfig;
|
||||
private privParameters: PropertyCollection;
|
||||
|
||||
constructor(
|
||||
public constructor(
|
||||
speechServiceConfig: SpeechServiceConfig,
|
||||
parameters: PropertyCollection) {
|
||||
this.privSpeechServiceConfig = speechServiceConfig ? speechServiceConfig : new SpeechServiceConfig(new Context(null));
|
||||
|
|
|
@ -5,17 +5,11 @@ import {
|
|||
ProxyInfo,
|
||||
WebsocketConnection,
|
||||
} from "../common.browser/Exports";
|
||||
import {
|
||||
OutputFormatPropertyName,
|
||||
} from "../common.speech/Exports";
|
||||
import {
|
||||
IConnection,
|
||||
IStringDictionary
|
||||
} from "../common/Exports";
|
||||
import {
|
||||
OutputFormat,
|
||||
PropertyId
|
||||
} from "../sdk/Exports";
|
||||
import { PropertyId } from "../sdk/Exports";
|
||||
import {
|
||||
ConnectionFactoryBase
|
||||
} from "./ConnectionFactoryBase";
|
||||
|
@ -33,10 +27,10 @@ export class TranscriberConnectionFactory extends ConnectionFactoryBase {
|
|||
|
||||
private readonly multiaudioRelativeUri: string = "/speech/recognition/multiaudio";
|
||||
|
||||
public create = (
|
||||
public create(
|
||||
config: RecognizerConfig,
|
||||
authInfo: AuthInfo,
|
||||
connectionId?: string): IConnection => {
|
||||
connectionId?: string): IConnection {
|
||||
|
||||
let endpoint: string = config.parameters.getProperty(PropertyId.SpeechServiceConnection_Endpoint, undefined);
|
||||
const region: string = config.parameters.getProperty(PropertyId.SpeechServiceConnection_Region, "centralus");
|
||||
|
|
|
@ -12,7 +12,7 @@ export class ConversationConnectionMessage extends ConnectionMessage {
|
|||
headers?: IStringDictionary<string>,
|
||||
id?: string) {
|
||||
super(messageType, body, headers, id);
|
||||
const json = JSON.parse(this.textBody);
|
||||
const json: { type: string } = JSON.parse(this.textBody) as { type: string };
|
||||
if (json.type !== undefined) {
|
||||
this.privConversationMessageType = json.type;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ import { IErrorMessages, IStringDictionary } from "../../common/Exports";
|
|||
import { Contracts } from "../../sdk/Contracts";
|
||||
import { PropertyCollection, PropertyId } from "../../sdk/Exports";
|
||||
import { ConversationConnectionConfig } from "./ConversationConnectionConfig";
|
||||
import { IConversationResponseError, IInternalConversation, IResponse } from "./ConversationTranslatorInterfaces";
|
||||
import { IConversationResponseError, IInternalConversation } from "./ConversationTranslatorInterfaces";
|
||||
|
||||
export class ConversationManager {
|
||||
|
||||
|
@ -40,7 +40,7 @@ export class ConversationManager {
|
|||
* @param callback
|
||||
* @param errorCallback
|
||||
*/
|
||||
public createOrJoin(args: PropertyCollection, conversationCode: string, cb?: any, err?: any): void {
|
||||
public createOrJoin(args: PropertyCollection, conversationCode: string, cb?: (c: any) => void, err?: (e: string) => void): void {
|
||||
|
||||
try {
|
||||
|
||||
|
@ -90,7 +90,7 @@ export class ConversationManager {
|
|||
const endpoint: string = `https://${endpointHost}${this.privRestPath}`;
|
||||
|
||||
// TODO: support a proxy and certificate validation
|
||||
this.privRestAdapter.request(RestRequestType.Post, endpoint, queryParams, null).then((response: IRestResponse) => {
|
||||
this.privRestAdapter.request(RestRequestType.Post, endpoint, queryParams, null).then((response: IRestResponse): void => {
|
||||
|
||||
const requestId: string = RestMessageAdapter.extractHeaderValue(this.privRequestParams.requestId, response.headers);
|
||||
|
||||
|
@ -122,22 +122,22 @@ export class ConversationManager {
|
|||
cb(conversation);
|
||||
} catch (e) {
|
||||
if (!!err) {
|
||||
err(e);
|
||||
err(e as string);
|
||||
}
|
||||
}
|
||||
cb = undefined;
|
||||
}
|
||||
/* tslint:disable:no-empty */
|
||||
}).catch( (e: any) => {});
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
}).catch( (): void => { });
|
||||
|
||||
} catch (error) {
|
||||
if (!!err) {
|
||||
if (error instanceof Error) {
|
||||
const typedError: Error = error as Error;
|
||||
const typedError: Error = error;
|
||||
err(typedError.name + ": " + typedError.message);
|
||||
|
||||
} else {
|
||||
err(error);
|
||||
err(error as string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -175,23 +175,23 @@ export class ConversationManager {
|
|||
const endpoint: string = `https://${endpointHost}${this.privRestPath}`;
|
||||
|
||||
// TODO: support a proxy and certificate validation
|
||||
this.privRestAdapter.request(RestRequestType.Delete, endpoint, queryParams, null).then((response: IRestResponse) => {
|
||||
this.privRestAdapter.request(RestRequestType.Delete, endpoint, queryParams, null).then((response: IRestResponse): void => {
|
||||
|
||||
if (!response.ok) {
|
||||
// ignore errors on delete
|
||||
}
|
||||
|
||||
resolve();
|
||||
/* tslint:disable:no-empty */
|
||||
}).catch( (e: any) => {});
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
}).catch( (): void => {});
|
||||
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
const typedError: Error = error as Error;
|
||||
const typedError: Error = error;
|
||||
reject(typedError.name + ": " + typedError.message);
|
||||
|
||||
} else {
|
||||
reject(error);
|
||||
reject(error as string);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -18,7 +18,7 @@ export class ConversationRequestSession {
|
|||
private privRequestCompletionDeferral: Deferred<void>;
|
||||
private privSessionId: string;
|
||||
|
||||
constructor(sessionId: string) {
|
||||
public constructor(sessionId: string) {
|
||||
this.privSessionId = sessionId;
|
||||
this.privRequestId = createNoDashGuid();
|
||||
this.privRequestCompletionDeferral = new Deferred<void>();
|
||||
|
@ -36,17 +36,17 @@ export class ConversationRequestSession {
|
|||
return this.privRequestCompletionDeferral.promise;
|
||||
}
|
||||
|
||||
public onPreConnectionStart = (authFetchEventId: string, connectionId: string): void => {
|
||||
public onPreConnectionStart(authFetchEventId: string, connectionId: string): void {
|
||||
this.privSessionId = connectionId;
|
||||
}
|
||||
|
||||
public onAuthCompleted = (isError: boolean, error?: string): void => {
|
||||
public onAuthCompleted(isError: boolean): void {
|
||||
if (isError) {
|
||||
this.onComplete();
|
||||
}
|
||||
}
|
||||
|
||||
public onConnectionEstablishCompleted = (statusCode: number, reason?: string): void => {
|
||||
public onConnectionEstablishCompleted(statusCode: number): void {
|
||||
if (statusCode === 200) {
|
||||
return;
|
||||
} else if (statusCode === 403) {
|
||||
|
@ -54,7 +54,7 @@ export class ConversationRequestSession {
|
|||
}
|
||||
}
|
||||
|
||||
public onServiceTurnEndResponse = (continuousRecognition: boolean): void => {
|
||||
public onServiceTurnEndResponse(continuousRecognition: boolean): void {
|
||||
if (!continuousRecognition) {
|
||||
this.onComplete();
|
||||
} else {
|
||||
|
@ -62,7 +62,7 @@ export class ConversationRequestSession {
|
|||
}
|
||||
}
|
||||
|
||||
public async dispose(error?: string): Promise<void> {
|
||||
public async dispose(): Promise<void> {
|
||||
if (!this.privIsDisposed) {
|
||||
// we should have completed by now. If we did not its an unknown error.
|
||||
this.privIsDisposed = true;
|
||||
|
@ -72,7 +72,7 @@ export class ConversationRequestSession {
|
|||
}
|
||||
}
|
||||
|
||||
private onComplete = (): void => {
|
||||
private onComplete(): void {
|
||||
//
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
// Licensed under the MIT license.
|
||||
|
||||
import {
|
||||
ConnectionMessage,
|
||||
ConnectionState,
|
||||
createNoDashGuid,
|
||||
Deferred,
|
||||
|
@ -52,7 +51,7 @@ import {
|
|||
TextResponsePayload
|
||||
} from "./ServiceMessages/Exports";
|
||||
|
||||
/***
|
||||
/**
|
||||
* The service adapter handles sending and receiving messages to the Conversation Translator websocket.
|
||||
*/
|
||||
export class ConversationServiceAdapter extends ServiceRecognizerBase {
|
||||
|
@ -61,10 +60,10 @@ export class ConversationServiceAdapter extends ServiceRecognizerBase {
|
|||
private privConversationAuthFetchEventId: string;
|
||||
private privConversationAuthentication: IAuthentication;
|
||||
private privConversationRequestSession: ConversationRequestSession;
|
||||
private privConnectionConfigPromise: Promise<IConnection>;
|
||||
private privConnectionConfigPromise: Promise<IConnection> = undefined;
|
||||
private privConnectionLoop: Promise<void>;
|
||||
private terminateMessageLoop: boolean;
|
||||
private privLastPartialUtteranceId: string = "";
|
||||
private privLastPartialUtteranceId: string;
|
||||
private privConversationIsDisposed: boolean;
|
||||
|
||||
public constructor(
|
||||
|
@ -76,13 +75,14 @@ export class ConversationServiceAdapter extends ServiceRecognizerBase {
|
|||
|
||||
super(authentication, connectionFactory, audioSource, recognizerConfig, conversationServiceConnector);
|
||||
|
||||
this.privLastPartialUtteranceId = "";
|
||||
this.privConversationServiceConnector = conversationServiceConnector;
|
||||
this.privConversationAuthentication = authentication;
|
||||
this.receiveMessageOverride = this.receiveConversationMessageOverride;
|
||||
this.recognizeOverride = this.noOp;
|
||||
this.postConnectImplOverride = this.conversationConnectImpl;
|
||||
this.configConnectionOverride = this.configConnection;
|
||||
this.disconnectOverride = this.privDisconnect;
|
||||
this.receiveMessageOverride = (): Promise<void> => this.receiveConversationMessageOverride();
|
||||
this.recognizeOverride = (): Promise<void> => this.noOp();
|
||||
this.postConnectImplOverride = (connection: Promise<IConnection>): Promise<IConnection> => this.conversationConnectImpl(connection);
|
||||
this.configConnectionOverride = (): Promise<IConnection> => this.configConnection();
|
||||
this.disconnectOverride = (): Promise<void> => this.privDisconnect();
|
||||
this.privConversationRequestSession = new ConversationRequestSession(createNoDashGuid());
|
||||
this.privConversationConnectionFactory = connectionFactory;
|
||||
this.privConversationIsDisposed = false;
|
||||
|
@ -94,7 +94,7 @@ export class ConversationServiceAdapter extends ServiceRecognizerBase {
|
|||
|
||||
public async dispose(reason?: string): Promise<void> {
|
||||
this.privConversationIsDisposed = true;
|
||||
if (this.privConnectionConfigPromise) {
|
||||
if (this.privConnectionConfigPromise !== undefined) {
|
||||
const connection: IConnection = await this.privConnectionConfigPromise;
|
||||
await connection.dispose(reason);
|
||||
}
|
||||
|
@ -109,8 +109,6 @@ export class ConversationServiceAdapter extends ServiceRecognizerBase {
|
|||
}
|
||||
|
||||
public async sendMessageAsync(message: string): Promise<void> {
|
||||
const sink: Deferred<void> = new Deferred<void>();
|
||||
|
||||
const connection: IConnection = await this.fetchConnection();
|
||||
|
||||
await connection.send(new ConversationConnectionMessage(MessageType.Text, message));
|
||||
|
@ -130,10 +128,8 @@ export class ConversationServiceAdapter extends ServiceRecognizerBase {
|
|||
return Promise.resolve();
|
||||
}
|
||||
|
||||
protected async processTypeSpecificMessages(
|
||||
connectionMessage: ConnectionMessage,
|
||||
successCallback?: (e: any) => void,
|
||||
errorCallBack?: (e: string) => void): Promise<boolean> {
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
protected async processTypeSpecificMessages(): Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -163,8 +159,9 @@ export class ConversationServiceAdapter extends ServiceRecognizerBase {
|
|||
}
|
||||
}
|
||||
|
||||
protected noOp = (): any => {
|
||||
protected noOp(): Promise<void> {
|
||||
// operation not supported
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -218,7 +215,7 @@ export class ConversationServiceAdapter extends ServiceRecognizerBase {
|
|||
|
||||
const participantsPayload: IParticipantsListPayloadResponse = ParticipantsListPayloadResponse.fromJSON(message.textBody);
|
||||
|
||||
const participantsResult: IInternalParticipant[] = participantsPayload.participants.map((p: IParticipantPayloadResponse) => {
|
||||
const participantsResult: IInternalParticipant[] = participantsPayload.participants.map((p: IParticipantPayloadResponse): IInternalParticipant => {
|
||||
const participant: IInternalParticipant = {
|
||||
avatar: p.avatar,
|
||||
displayName: p.nickname,
|
||||
|
@ -400,6 +397,7 @@ export class ConversationServiceAdapter extends ServiceRecognizerBase {
|
|||
*/
|
||||
case "disconnectsession":
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const disconnectParticipant: IInternalParticipant = {
|
||||
id: commandPayload.participantId
|
||||
};
|
||||
|
@ -408,11 +406,11 @@ export class ConversationServiceAdapter extends ServiceRecognizerBase {
|
|||
|
||||
case "token":
|
||||
const token = new CognitiveTokenAuthentication(
|
||||
(authFetchEventId: string): Promise<string> => {
|
||||
(): Promise<string> => {
|
||||
const authorizationToken = commandPayload.token;
|
||||
return Promise.resolve(authorizationToken);
|
||||
},
|
||||
(authFetchEventId: string): Promise<string> => {
|
||||
(): Promise<string> => {
|
||||
const authorizationToken = commandPayload.token;
|
||||
return Promise.resolve(authorizationToken);
|
||||
});
|
||||
|
@ -531,7 +529,7 @@ export class ConversationServiceAdapter extends ServiceRecognizerBase {
|
|||
const r = await messageRetrievalPromise;
|
||||
return r;
|
||||
} catch (error) {
|
||||
this.cancelRecognition(this.privRequestSession ? this.privRequestSession.sessionId : "", this.privRequestSession ? this.privRequestSession.requestId : "", CancellationReason.Error, CancellationErrorCode.RuntimeError, error);
|
||||
this.cancelRecognition(this.privRequestSession ? this.privRequestSession.sessionId : "", this.privRequestSession ? this.privRequestSession.requestId : "", CancellationReason.Error, CancellationErrorCode.RuntimeError, error as string);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -541,17 +539,17 @@ export class ConversationServiceAdapter extends ServiceRecognizerBase {
|
|||
if (this.isDisposed()) {
|
||||
return Promise.resolve<IConnection>(undefined);
|
||||
}
|
||||
if (this.privConnectionConfigPromise) {
|
||||
if (this.privConnectionConfigPromise !== undefined) {
|
||||
return this.privConnectionConfigPromise.then((connection: IConnection): Promise<IConnection> => {
|
||||
if (connection.state() === ConnectionState.Disconnected) {
|
||||
this.privConnectionId = null;
|
||||
this.privConnectionConfigPromise = null;
|
||||
this.privConnectionConfigPromise = undefined;
|
||||
return this.configConnection();
|
||||
}
|
||||
return this.privConnectionConfigPromise;
|
||||
}, (error: string): Promise<IConnection> => {
|
||||
}, (): Promise<IConnection> => {
|
||||
this.privConnectionId = null;
|
||||
this.privConnectionConfigPromise = null;
|
||||
this.privConnectionConfigPromise = undefined;
|
||||
return this.configConnection();
|
||||
});
|
||||
}
|
||||
|
@ -559,9 +557,7 @@ export class ConversationServiceAdapter extends ServiceRecognizerBase {
|
|||
return Promise.resolve<IConnection>(undefined);
|
||||
}
|
||||
|
||||
this.privConnectionConfigPromise = this.connectImpl().then((connection: IConnection): any => {
|
||||
return connection;
|
||||
});
|
||||
this.privConnectionConfigPromise = this.connectImpl().then((connection: IConnection): IConnection => connection);
|
||||
|
||||
return this.privConnectionConfigPromise;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
import { SessionEventArgs } from "../../sdk/Exports";
|
||||
/* eslint-disable max-classes-per-file */
|
||||
import { ConversationTranslationResult, SessionEventArgs } from "../../sdk/Exports";
|
||||
import { IInternalParticipant } from "./ConversationTranslatorInterfaces";
|
||||
|
||||
export class MuteAllEventArgs extends SessionEventArgs {
|
||||
|
@ -17,7 +18,6 @@ export class MuteAllEventArgs extends SessionEventArgs {
|
|||
}
|
||||
}
|
||||
|
||||
// tslint:disable-next-line: max-classes-per-file
|
||||
export class LockRoomEventArgs extends SessionEventArgs {
|
||||
private privIsLocked: boolean;
|
||||
|
||||
|
@ -32,7 +32,6 @@ export class LockRoomEventArgs extends SessionEventArgs {
|
|||
}
|
||||
}
|
||||
|
||||
// tslint:disable-next-line: max-classes-per-file
|
||||
export class ParticipantEventArgs extends SessionEventArgs {
|
||||
private privParticipant: IInternalParticipant;
|
||||
|
||||
|
@ -46,7 +45,6 @@ export class ParticipantEventArgs extends SessionEventArgs {
|
|||
}
|
||||
}
|
||||
|
||||
// tslint:disable-next-line: max-classes-per-file
|
||||
export class ParticipantAttributeEventArgs extends SessionEventArgs {
|
||||
private privValue: boolean | number | string | string[];
|
||||
private privKey: string;
|
||||
|
@ -72,7 +70,6 @@ export class ParticipantAttributeEventArgs extends SessionEventArgs {
|
|||
}
|
||||
}
|
||||
|
||||
// tslint:disable-next-line: max-classes-per-file
|
||||
export class ParticipantsListEventArgs extends SessionEventArgs {
|
||||
|
||||
private privRoomId: string;
|
||||
|
@ -129,19 +126,18 @@ export class ParticipantsListEventArgs extends SessionEventArgs {
|
|||
}
|
||||
}
|
||||
|
||||
// tslint:disable-next-line: max-classes-per-file
|
||||
export class ConversationReceivedTranslationEventArgs {
|
||||
private privPayload: any;
|
||||
private privPayload: ConversationTranslationResult;
|
||||
private privCommand: string;
|
||||
private privSessionId: string;
|
||||
|
||||
public constructor(command: string, payload: any, sessionId?: string) {
|
||||
public constructor(command: string, payload: ConversationTranslationResult, sessionId?: string) {
|
||||
this.privPayload = payload;
|
||||
this.privCommand = command;
|
||||
this.privSessionId = sessionId;
|
||||
}
|
||||
|
||||
public get payload(): any {
|
||||
public get payload(): ConversationTranslationResult {
|
||||
return this.privPayload;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ import {
|
|||
ConversationExpirationEventArgs,
|
||||
ConversationTranslationCanceledEventArgs,
|
||||
SessionEventArgs,
|
||||
VoiceSignature,
|
||||
} from "../../sdk/Exports";
|
||||
// import { ConversationClient } from "./ConversationConnection";
|
||||
import {
|
||||
|
@ -61,14 +60,16 @@ export interface IInternalParticipant {
|
|||
isHost?: boolean;
|
||||
isMuted?: boolean;
|
||||
isUsingTts?: boolean;
|
||||
profanity?: boolean;
|
||||
preferredLanguage?: string;
|
||||
translateToLanguages?: string[];
|
||||
voice?: string;
|
||||
}
|
||||
|
||||
/** Users participating in the conversation */
|
||||
export class InternalParticipants {
|
||||
|
||||
constructor(public participants: IInternalParticipant[] = [], public meId?: string) {
|
||||
public constructor(public participants: IInternalParticipant[] = [], public meId?: string) {
|
||||
|
||||
}
|
||||
|
||||
|
@ -97,7 +98,7 @@ export class InternalParticipants {
|
|||
* @param id
|
||||
*/
|
||||
public getParticipantIndex(id: string): number {
|
||||
return this.participants.findIndex((p: IInternalParticipant) => p.id === id);
|
||||
return this.participants.findIndex((p: IInternalParticipant): boolean => p.id === id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -105,21 +106,21 @@ export class InternalParticipants {
|
|||
* @param id
|
||||
*/
|
||||
public getParticipant(id: string): IInternalParticipant {
|
||||
return this.participants.find((p: IInternalParticipant) => p.id === id);
|
||||
return this.participants.find((p: IInternalParticipant): boolean => p.id === id);
|
||||
}
|
||||
|
||||
/***
|
||||
/**
|
||||
* Remove a participant from the participants list.
|
||||
*/
|
||||
public deleteParticipant(id: string): void {
|
||||
this.participants = this.participants.filter((p: IInternalParticipant) => p.id !== id);
|
||||
this.participants = this.participants.filter((p: IInternalParticipant): boolean => p.id !== id);
|
||||
}
|
||||
|
||||
/***
|
||||
/**
|
||||
* Helper to return the conversation host.
|
||||
*/
|
||||
public get host(): IInternalParticipant {
|
||||
return this.participants.find((p: IInternalParticipant) => p.isHost === true );
|
||||
return this.participants.find((p: IInternalParticipant): boolean => p.isHost === true );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// eslint-disable-next-line max-classes-per-file
|
||||
import {
|
||||
IAuthentication,
|
||||
IConnectionFactory,
|
||||
|
@ -42,7 +43,6 @@ import {
|
|||
} from "./ConversationTranslatorEventArgs";
|
||||
import {
|
||||
ConversationRecognizer,
|
||||
ConversationTranslatorMessageTypes
|
||||
} from "./ConversationTranslatorInterfaces";
|
||||
|
||||
export class ConversationRecognizerFactory {
|
||||
|
@ -55,7 +55,6 @@ export class ConversationRecognizerFactory {
|
|||
* Sends messages to the Conversation Translator websocket and listens for incoming events containing websocket messages.
|
||||
* Based off the recognizers in the SDK folder.
|
||||
*/
|
||||
// tslint:disable-next-line:max-classes-per-file
|
||||
export class ConversationTranslatorRecognizer extends Recognizer implements ConversationRecognizer {
|
||||
|
||||
private privIsDisposed: boolean;
|
||||
|
@ -135,10 +134,10 @@ export class ConversationTranslatorRecognizer extends Recognizer implements Conv
|
|||
} catch (error) {
|
||||
if (!!err) {
|
||||
if (error instanceof Error) {
|
||||
const typedError: Error = error as Error;
|
||||
const typedError: Error = error;
|
||||
err(typedError.name + ": " + typedError.message);
|
||||
} else {
|
||||
err(error);
|
||||
err(error as string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -151,13 +150,14 @@ export class ConversationTranslatorRecognizer extends Recognizer implements Conv
|
|||
try {
|
||||
Contracts.throwIfDisposed(this.privIsDisposed);
|
||||
if (this.privTimeoutToken !== undefined) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||
this.privClearTimeout(this.privTimeoutToken);
|
||||
}
|
||||
this.privReco.disconnect().then(() => {
|
||||
this.privReco.disconnect().then((): void => {
|
||||
if (!!cb) {
|
||||
cb();
|
||||
}
|
||||
}, (error: string) => {
|
||||
}, (error: string): void => {
|
||||
if (!!err) {
|
||||
err(error);
|
||||
}
|
||||
|
@ -165,10 +165,10 @@ export class ConversationTranslatorRecognizer extends Recognizer implements Conv
|
|||
} catch (error) {
|
||||
if (!!err) {
|
||||
if (error instanceof Error) {
|
||||
const typedError: Error = error as Error;
|
||||
const typedError: Error = error;
|
||||
err(typedError.name + ": " + typedError.message);
|
||||
} else {
|
||||
err(error);
|
||||
err(error as string);
|
||||
}
|
||||
}
|
||||
// Destroy the recognizer.
|
||||
|
@ -192,10 +192,10 @@ export class ConversationTranslatorRecognizer extends Recognizer implements Conv
|
|||
} catch (error) {
|
||||
if (!!err) {
|
||||
if (error instanceof Error) {
|
||||
const typedError: Error = error as Error;
|
||||
const typedError: Error = error;
|
||||
err(typedError.name + ": " + typedError.message);
|
||||
} else {
|
||||
err(error);
|
||||
err(error as string);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -212,8 +212,10 @@ export class ConversationTranslatorRecognizer extends Recognizer implements Conv
|
|||
*/
|
||||
public async close(): Promise<void> {
|
||||
if (!this.privIsDisposed) {
|
||||
this.privConnection?.closeConnection();
|
||||
this.privConnection?.close();
|
||||
if (!!this.privConnection) {
|
||||
this.privConnection.closeConnection();
|
||||
this.privConnection.close();
|
||||
}
|
||||
this.privConnection = undefined;
|
||||
await this.dispose(true);
|
||||
}
|
||||
|
@ -229,6 +231,7 @@ export class ConversationTranslatorRecognizer extends Recognizer implements Conv
|
|||
}
|
||||
if (disposing) {
|
||||
if (this.privTimeoutToken !== undefined) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||
this.privClearTimeout(this.privTimeoutToken);
|
||||
}
|
||||
this.privIsDisposed = true;
|
||||
|
@ -270,33 +273,32 @@ export class ConversationTranslatorRecognizer extends Recognizer implements Conv
|
|||
|
||||
private sendMessage(msg: string, cb?: Callback, err?: Callback): void {
|
||||
const withAsync = this.privReco as ConversationServiceAdapter;
|
||||
function PromiseToEmptyCallback<T>(promise: Promise<T>, cb?: Callback, err?: Callback): void {
|
||||
if (!!promise) {
|
||||
promise.then((result: T): void => {
|
||||
const PromiseToEmptyCallback = <T>(promise: Promise<T>, cb?: Callback, err?: Callback): void => {
|
||||
if (promise !== undefined) {
|
||||
promise.then((): void => {
|
||||
try {
|
||||
if (!!cb) {
|
||||
cb();
|
||||
}
|
||||
} catch (e) {
|
||||
if (!!err) {
|
||||
err(`'Unhandled error on promise callback: ${e}'`);
|
||||
err(`'Unhandled error on promise callback: ${e as string}'`);
|
||||
}
|
||||
}
|
||||
}, (reason: any) => {
|
||||
}, (reason: any): void => {
|
||||
try {
|
||||
if (!!err) {
|
||||
err(reason);
|
||||
}
|
||||
/* tslint:disable:no-empty */
|
||||
} catch (error) {
|
||||
}
|
||||
// eslint-disable-next-line no-empty
|
||||
} catch (error) { }
|
||||
});
|
||||
} else {
|
||||
if (!!err) {
|
||||
err("Null promise");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
PromiseToEmptyCallback(withAsync.sendMessageAsync(msg), cb, err);
|
||||
this.resetConversationTimeout();
|
||||
|
@ -304,6 +306,7 @@ export class ConversationTranslatorRecognizer extends Recognizer implements Conv
|
|||
|
||||
private resetConversationTimeout(): void {
|
||||
if (this.privTimeoutToken !== undefined) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||
this.privClearTimeout(this.privTimeoutToken);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
import {
|
||||
ConnectionMessage,
|
||||
Deferred,
|
||||
IStringDictionary,
|
||||
IWebsocketMessageFormatter,
|
||||
MessageType,
|
||||
RawWebsocketMessage,
|
||||
|
@ -19,7 +18,7 @@ export class ConversationWebsocketMessageFormatter implements IWebsocketMessageF
|
|||
/**
|
||||
* Format incoming messages: text (speech partial/final, IM) or binary (tts)
|
||||
*/
|
||||
public toConnectionMessage = (message: RawWebsocketMessage): Promise<ConversationConnectionMessage> => {
|
||||
public toConnectionMessage(message: RawWebsocketMessage): Promise<ConversationConnectionMessage> {
|
||||
const deferral = new Deferred<ConversationConnectionMessage>();
|
||||
|
||||
try {
|
||||
|
@ -30,7 +29,7 @@ export class ConversationWebsocketMessageFormatter implements IWebsocketMessageF
|
|||
deferral.resolve(new ConversationConnectionMessage(message.messageType, message.binaryContent, undefined, message.id));
|
||||
}
|
||||
} catch (e) {
|
||||
deferral.reject(`Error formatting the message. Error: ${e}`);
|
||||
deferral.reject(`Error formatting the message. Error: ${e as string}`);
|
||||
}
|
||||
|
||||
return deferral.promise;
|
||||
|
@ -39,7 +38,7 @@ export class ConversationWebsocketMessageFormatter implements IWebsocketMessageF
|
|||
/**
|
||||
* Format outgoing messages: text (commands or IM)
|
||||
*/
|
||||
public fromConnectionMessage = (message: ConnectionMessage): Promise<RawWebsocketMessage> => {
|
||||
public fromConnectionMessage(message: ConnectionMessage): Promise<RawWebsocketMessage> {
|
||||
|
||||
const deferral = new Deferred<RawWebsocketMessage>();
|
||||
|
||||
|
@ -49,7 +48,7 @@ export class ConversationWebsocketMessageFormatter implements IWebsocketMessageF
|
|||
deferral.resolve(new RawWebsocketMessage(MessageType.Text, payload, message.id));
|
||||
}
|
||||
} catch (e) {
|
||||
deferral.reject(`Error formatting the message. ${e}`);
|
||||
deferral.reject(`Error formatting the message. ${e as string}`);
|
||||
}
|
||||
|
||||
return deferral.promise;
|
||||
|
|
|
@ -15,15 +15,13 @@ export interface ICommandResponsePayload {
|
|||
token?: string;
|
||||
}
|
||||
|
||||
const parseCommandResponse = (json: string): ICommandResponsePayload => JSON.parse(json) as ICommandResponsePayload;
|
||||
|
||||
export class CommandResponsePayload implements ICommandResponsePayload {
|
||||
private privCommandResponse: ICommandResponsePayload;
|
||||
|
||||
public constructor(json: string) {
|
||||
this.privCommandResponse = JSON.parse(json);
|
||||
}
|
||||
|
||||
public static fromJSON(json: string): CommandResponsePayload {
|
||||
return new CommandResponsePayload(json);
|
||||
this.privCommandResponse = parseCommandResponse(json);
|
||||
}
|
||||
|
||||
public get type(): string {
|
||||
|
@ -50,4 +48,9 @@ export class CommandResponsePayload implements ICommandResponsePayload {
|
|||
public get token(): string {
|
||||
return this.privCommandResponse.token;
|
||||
}
|
||||
|
||||
public static fromJSON(json: string): CommandResponsePayload {
|
||||
return new CommandResponsePayload(json);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
/* eslint-disable max-classes-per-file */
|
||||
/**
|
||||
* Defines the payload for incoming list of participants
|
||||
*/
|
||||
|
@ -31,15 +32,14 @@ export interface IParticipantPayloadResponse {
|
|||
avatar?: string;
|
||||
}
|
||||
|
||||
const parseListResponse = (json: string): IParticipantsListPayloadResponse => JSON.parse(json) as IParticipantsListPayloadResponse;
|
||||
const parseParticipantResponse = (json: string): IParticipantPayloadResponse => JSON.parse(json) as IParticipantPayloadResponse;
|
||||
|
||||
export class ParticipantsListPayloadResponse implements IParticipantsListPayloadResponse {
|
||||
private privParticipantsPayloadResponse: IParticipantsListPayloadResponse;
|
||||
|
||||
private constructor(json: string) {
|
||||
this.privParticipantsPayloadResponse = JSON.parse(json);
|
||||
}
|
||||
|
||||
public static fromJSON(json: string): ParticipantsListPayloadResponse {
|
||||
return new ParticipantsListPayloadResponse(json);
|
||||
this.privParticipantsPayloadResponse = parseListResponse(json);
|
||||
}
|
||||
|
||||
public get roomid(): string {
|
||||
|
@ -86,19 +86,18 @@ export class ParticipantsListPayloadResponse implements IParticipantsListPayload
|
|||
return this.privParticipantsPayloadResponse.type;
|
||||
}
|
||||
|
||||
public static fromJSON(json: string): ParticipantsListPayloadResponse {
|
||||
return new ParticipantsListPayloadResponse(json);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// tslint:disable-next-line: max-classes-per-file
|
||||
export class ParticipantPayloadResponse implements IParticipantPayloadResponse {
|
||||
|
||||
private privParticipantPayloadResponse: IParticipantPayloadResponse;
|
||||
|
||||
private constructor(json: string) {
|
||||
this.privParticipantPayloadResponse = JSON.parse(json);
|
||||
}
|
||||
|
||||
public static fromJSON(json: string): ParticipantPayloadResponse {
|
||||
return new ParticipantPayloadResponse(json);
|
||||
this.privParticipantPayloadResponse = parseParticipantResponse(json);
|
||||
}
|
||||
|
||||
public get nickname(): string {
|
||||
|
@ -128,4 +127,9 @@ export class ParticipantPayloadResponse implements IParticipantPayloadResponse {
|
|||
public get avatar(): string {
|
||||
return this.privParticipantPayloadResponse.avatar;
|
||||
}
|
||||
|
||||
public static fromJSON(json: string): ParticipantPayloadResponse {
|
||||
return new ParticipantPayloadResponse(json);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
/* eslint-disable max-classes-per-file */
|
||||
/**
|
||||
* Defines the payload for incoming translation messages
|
||||
*/
|
||||
|
@ -29,16 +30,15 @@ export interface ITextResponsePayload extends ITranslationCommandMessage {
|
|||
originalText: string;
|
||||
}
|
||||
|
||||
const parseSpeechResponse = (json: string): ISpeechResponsePayload => JSON.parse(json) as ISpeechResponsePayload;
|
||||
const parseTextResponse = (json: string): ITextResponsePayload => JSON.parse(json) as ITextResponsePayload;
|
||||
|
||||
export class SpeechResponsePayload implements ISpeechResponsePayload {
|
||||
|
||||
private privSpeechResponse: ISpeechResponsePayload;
|
||||
|
||||
private constructor(json: string) {
|
||||
this.privSpeechResponse = JSON.parse(json);
|
||||
}
|
||||
|
||||
public static fromJSON(json: string): SpeechResponsePayload {
|
||||
return new SpeechResponsePayload(json);
|
||||
this.privSpeechResponse = parseSpeechResponse(json);
|
||||
}
|
||||
|
||||
public get recognition(): string {
|
||||
|
@ -80,19 +80,19 @@ export class SpeechResponsePayload implements ISpeechResponsePayload {
|
|||
public get isFinal(): boolean {
|
||||
return this.privSpeechResponse.type === "final";
|
||||
}
|
||||
|
||||
public static fromJSON(json: string): SpeechResponsePayload {
|
||||
return new SpeechResponsePayload(json);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// tslint:disable-next-line: max-classes-per-file
|
||||
export class TextResponsePayload implements ITextResponsePayload {
|
||||
|
||||
private privTextResponse: ITextResponsePayload;
|
||||
|
||||
private constructor(json: string) {
|
||||
this.privTextResponse = JSON.parse(json);
|
||||
}
|
||||
|
||||
public static fromJSON(json: string): TextResponsePayload {
|
||||
return new TextResponsePayload(json);
|
||||
this.privTextResponse = parseTextResponse(json);
|
||||
}
|
||||
|
||||
public get originalText(): string {
|
||||
|
@ -130,4 +130,9 @@ export class TextResponsePayload implements ITextResponsePayload {
|
|||
public get type(): string {
|
||||
return this.privTextResponse.type;
|
||||
}
|
||||
|
||||
public static fromJSON(json: string): TextResponsePayload {
|
||||
return new TextResponsePayload(json);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -30,6 +30,19 @@ import {
|
|||
} from "../Exports";
|
||||
|
||||
export class TranscriberRecognizer extends Recognizer {
|
||||
|
||||
public recognizing: (sender: Recognizer, event: SpeechRecognitionEventArgs) => void;
|
||||
|
||||
public recognized: (sender: Recognizer, event: SpeechRecognitionEventArgs) => void;
|
||||
|
||||
public canceled: (sender: Recognizer, event: CancellationEventArgs) => void;
|
||||
|
||||
public conversationCanceled: (sender: Recognizer, event: CancellationEventArgs) => void;
|
||||
|
||||
public conversationStarted: (sender: Recognizer, event: SessionEventArgs) => void;
|
||||
|
||||
public conversationStopped: (sender: Recognizer, event: SessionEventArgs) => void;
|
||||
|
||||
private privDisposedRecognizer: boolean;
|
||||
private privConversation: Conversation;
|
||||
|
||||
|
@ -50,21 +63,14 @@ export class TranscriberRecognizer extends Recognizer {
|
|||
this.privDisposedRecognizer = false;
|
||||
}
|
||||
|
||||
public recognizing: (sender: Recognizer, event: SpeechRecognitionEventArgs) => void;
|
||||
public get speechRecognitionLanguage(): string {
|
||||
Contracts.throwIfDisposed(this.privDisposedRecognizer);
|
||||
|
||||
public recognized: (sender: Recognizer, event: SpeechRecognitionEventArgs) => void;
|
||||
return this.properties.getProperty(PropertyId.SpeechServiceConnection_RecoLanguage);
|
||||
}
|
||||
|
||||
public canceled: (sender: Recognizer, event: CancellationEventArgs) => void;
|
||||
|
||||
public conversationCanceled: (sender: Recognizer, event: CancellationEventArgs) => void;
|
||||
|
||||
public conversationStarted: (sender: Recognizer, event: SessionEventArgs) => void;
|
||||
|
||||
public conversationStopped: (sender: Recognizer, event: SessionEventArgs) => void;
|
||||
|
||||
public getConversationInfo(): ConversationInfo {
|
||||
Contracts.throwIfNullOrUndefined(this.privConversation, "Conversation");
|
||||
return this.privConversation.conversationInfo;
|
||||
public get properties(): PropertyCollection {
|
||||
return this.privProperties;
|
||||
}
|
||||
|
||||
public get authorizationToken(): string {
|
||||
|
@ -81,14 +87,9 @@ export class TranscriberRecognizer extends Recognizer {
|
|||
this.privConversation = c;
|
||||
}
|
||||
|
||||
public get speechRecognitionLanguage(): string {
|
||||
Contracts.throwIfDisposed(this.privDisposedRecognizer);
|
||||
|
||||
return this.properties.getProperty(PropertyId.SpeechServiceConnection_RecoLanguage);
|
||||
}
|
||||
|
||||
public get properties(): PropertyCollection {
|
||||
return this.privProperties;
|
||||
public getConversationInfo(): ConversationInfo {
|
||||
Contracts.throwIfNullOrUndefined(this.privConversation, "Conversation");
|
||||
return this.privConversation.conversationInfo;
|
||||
}
|
||||
|
||||
public startContinuousRecognitionAsync(cb?: () => void, err?: (e: string) => void): void {
|
||||
|
|
|
@ -18,6 +18,7 @@ import {
|
|||
SpeechRecognitionResult,
|
||||
} from "../sdk/Exports";
|
||||
import { ConversationInfo } from "../sdk/Transcription/Exports";
|
||||
import { ConversationProperties } from "../sdk/Transcription/IConversation";
|
||||
import {
|
||||
CancellationErrorCodePropertyName,
|
||||
DetailedSpeechPhrase,
|
||||
|
@ -34,7 +35,7 @@ import { IConnectionFactory } from "./IConnectionFactory";
|
|||
import { RecognizerConfig } from "./RecognizerConfig";
|
||||
import { SpeechConnectionMessage } from "./SpeechConnectionMessage.Internal";
|
||||
|
||||
// tslint:disable-next-line:max-classes-per-file
|
||||
// eslint-disable-next-line max-classes-per-file
|
||||
export class TranscriptionServiceRecognizer extends ServiceRecognizerBase {
|
||||
|
||||
private privTranscriberRecognizer: TranscriberRecognizer;
|
||||
|
@ -47,7 +48,7 @@ export class TranscriptionServiceRecognizer extends ServiceRecognizerBase {
|
|||
transcriber: TranscriberRecognizer) {
|
||||
super(authentication, connectionFactory, audioSource, recognizerConfig, transcriber);
|
||||
this.privTranscriberRecognizer = transcriber;
|
||||
this.sendPrePayloadJSONOverride = this.sendTranscriptionStartJSON;
|
||||
this.sendPrePayloadJSONOverride = (connection: IConnection): Promise<void> => this.sendTranscriptionStartJSON(connection);
|
||||
}
|
||||
|
||||
public async sendSpeechEventAsync(info: ConversationInfo, command: string): Promise<void> {
|
||||
|
@ -90,7 +91,7 @@ export class TranscriptionServiceRecognizer extends ServiceRecognizerBase {
|
|||
if (!!this.privTranscriberRecognizer.recognizing) {
|
||||
try {
|
||||
this.privTranscriberRecognizer.recognizing(this.privTranscriberRecognizer, ev);
|
||||
/* tslint:disable:no-empty */
|
||||
/* eslint-disable no-empty */
|
||||
} catch (error) {
|
||||
// Not going to let errors in the event handler
|
||||
// trip things up.
|
||||
|
@ -152,7 +153,7 @@ export class TranscriptionServiceRecognizer extends ServiceRecognizerBase {
|
|||
if (!!this.privTranscriberRecognizer.recognized) {
|
||||
try {
|
||||
this.privTranscriberRecognizer.recognized(this.privTranscriberRecognizer, event);
|
||||
/* tslint:disable:no-empty */
|
||||
/* eslint-disable no-empty */
|
||||
} catch (error) {
|
||||
// Not going to let errors in the event handler
|
||||
// trip things up.
|
||||
|
@ -165,7 +166,7 @@ export class TranscriptionServiceRecognizer extends ServiceRecognizerBase {
|
|||
this.privSuccessCallback(result);
|
||||
} catch (e) {
|
||||
if (!!this.privErrorCallback) {
|
||||
this.privErrorCallback(e);
|
||||
this.privErrorCallback(e as string);
|
||||
}
|
||||
}
|
||||
// Only invoke the call back once.
|
||||
|
@ -203,7 +204,7 @@ export class TranscriptionServiceRecognizer extends ServiceRecognizerBase {
|
|||
sessionId);
|
||||
try {
|
||||
this.privTranscriberRecognizer.canceled(this.privTranscriberRecognizer, cancelEvent);
|
||||
/* tslint:disable:no-empty */
|
||||
/* eslint-disable no-empty */
|
||||
} catch { }
|
||||
}
|
||||
|
||||
|
@ -223,7 +224,7 @@ export class TranscriptionServiceRecognizer extends ServiceRecognizerBase {
|
|||
try {
|
||||
this.privSuccessCallback(result);
|
||||
this.privSuccessCallback = undefined;
|
||||
/* tslint:disable:no-empty */
|
||||
/* eslint-disable no-empty */
|
||||
} catch { }
|
||||
}
|
||||
}
|
||||
|
@ -238,7 +239,7 @@ export class TranscriptionServiceRecognizer extends ServiceRecognizerBase {
|
|||
return;
|
||||
}
|
||||
|
||||
protected sendSpeechEvent = (connection: IConnection, payload: { [id: string]: any }): Promise<void> => {
|
||||
protected sendSpeechEvent(connection: IConnection, payload: { [id: string]: any }): Promise<void> {
|
||||
const speechEventJson = JSON.stringify(payload);
|
||||
|
||||
if (speechEventJson) {
|
||||
|
@ -253,14 +254,10 @@ export class TranscriptionServiceRecognizer extends ServiceRecognizerBase {
|
|||
}
|
||||
|
||||
private createSpeechEventPayload(info: ConversationInfo, command: string): { [id: string]: any } {
|
||||
const meeting: string = "meeting";
|
||||
const eventDict: { [id: string]: any } = { id: meeting, name: command, meeting: info.conversationProperties };
|
||||
const idString: string = "id";
|
||||
const attendees: string = "attendees";
|
||||
const record: string = "record";
|
||||
eventDict[meeting][idString] = info.id;
|
||||
eventDict[meeting][attendees] = info.participants;
|
||||
eventDict[meeting][record] = info.conversationProperties.audiorecording === "on" ? "true" : "false";
|
||||
const eventDict: { id: string; name: string; meeting: ConversationProperties } = { id: "meeting", name: command, meeting: info.conversationProperties };
|
||||
eventDict.meeting.id = info.id;
|
||||
eventDict.meeting.attendees = info.participants;
|
||||
eventDict.meeting.record = info.conversationProperties.audiorecording === "on" ? "true" : "false";
|
||||
return eventDict;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@ import {
|
|||
} from "./ConnectionFactoryBase";
|
||||
import {
|
||||
AuthInfo,
|
||||
IConnectionFactory,
|
||||
RecognizerConfig,
|
||||
WebsocketMessageFormatter,
|
||||
} from "./Exports";
|
||||
|
@ -26,10 +25,10 @@ import { QueryParameterNames } from "./QueryParameterNames";
|
|||
|
||||
export class TranslationConnectionFactory extends ConnectionFactoryBase {
|
||||
|
||||
public create = (
|
||||
public create(
|
||||
config: RecognizerConfig,
|
||||
authInfo: AuthInfo,
|
||||
connectionId?: string): IConnection => {
|
||||
connectionId?: string): IConnection {
|
||||
|
||||
let endpoint: string = config.parameters.getProperty(PropertyId.SpeechServiceConnection_Endpoint, undefined);
|
||||
if (!endpoint) {
|
||||
|
|
|
@ -13,7 +13,6 @@ import {
|
|||
PropertyCollection,
|
||||
PropertyId,
|
||||
ResultReason,
|
||||
SpeechRecognitionResult,
|
||||
TranslationRecognitionCanceledEventArgs,
|
||||
TranslationRecognitionEventArgs,
|
||||
TranslationRecognitionResult,
|
||||
|
@ -38,7 +37,7 @@ import { RecognizerConfig } from "./RecognizerConfig";
|
|||
import { ITranslationPhrase } from "./ServiceMessages/TranslationPhrase";
|
||||
import { SpeechConnectionMessage } from "./SpeechConnectionMessage.Internal";
|
||||
|
||||
// tslint:disable-next-line:max-classes-per-file
|
||||
// eslint-disable-next-line max-classes-per-file
|
||||
export class TranslationServiceRecognizer extends ServiceRecognizerBase {
|
||||
private privTranslationRecognizer: TranslationRecognizer;
|
||||
|
||||
|
@ -51,11 +50,11 @@ export class TranslationServiceRecognizer extends ServiceRecognizerBase {
|
|||
|
||||
super(authentication, connectionFactory, audioSource, recognizerConfig, translationRecognizer);
|
||||
this.privTranslationRecognizer = translationRecognizer;
|
||||
this.connectionEvents.attach(async (connectionEvent: ConnectionEvent): Promise<void> => {
|
||||
this.connectionEvents.attach((connectionEvent: ConnectionEvent): void => {
|
||||
if (connectionEvent.name === "ConnectionEstablishedEvent") {
|
||||
this.privTranslationRecognizer.onConnection();
|
||||
} else if (connectionEvent.name === "ConnectionClosedEvent") {
|
||||
await this.privTranslationRecognizer.onDisconnection();
|
||||
void this.privTranslationRecognizer.onDisconnection();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -76,7 +75,7 @@ export class TranslationServiceRecognizer extends ServiceRecognizerBase {
|
|||
if (!!this.privTranslationRecognizer.recognized) {
|
||||
try {
|
||||
this.privTranslationRecognizer.recognized(this.privTranslationRecognizer, result);
|
||||
/* tslint:disable:no-empty */
|
||||
/* eslint-disable no-empty */
|
||||
} catch (error) {
|
||||
// Not going to let errors in the event handler
|
||||
// trip things up.
|
||||
|
@ -89,7 +88,7 @@ export class TranslationServiceRecognizer extends ServiceRecognizerBase {
|
|||
this.privSuccessCallback(result.result);
|
||||
} catch (e) {
|
||||
if (!!this.privErrorCallback) {
|
||||
this.privErrorCallback(e);
|
||||
this.privErrorCallback(e as string);
|
||||
}
|
||||
}
|
||||
// Only invoke the call back once.
|
||||
|
@ -128,7 +127,7 @@ export class TranslationServiceRecognizer extends ServiceRecognizerBase {
|
|||
if (!!this.privTranslationRecognizer.recognized) {
|
||||
try {
|
||||
this.privTranslationRecognizer.recognized(this.privTranslationRecognizer, ev);
|
||||
/* tslint:disable:no-empty */
|
||||
/* eslint-disable no-empty */
|
||||
} catch (error) {
|
||||
// Not going to let errors in the event handler
|
||||
// trip things up.
|
||||
|
@ -142,7 +141,7 @@ export class TranslationServiceRecognizer extends ServiceRecognizerBase {
|
|||
this.privSuccessCallback(result);
|
||||
} catch (e) {
|
||||
if (!!this.privErrorCallback) {
|
||||
this.privErrorCallback(e);
|
||||
this.privErrorCallback(e as string);
|
||||
}
|
||||
}
|
||||
// Only invoke the call back once.
|
||||
|
@ -170,7 +169,7 @@ export class TranslationServiceRecognizer extends ServiceRecognizerBase {
|
|||
if (!!this.privTranslationRecognizer.recognizing) {
|
||||
try {
|
||||
this.privTranslationRecognizer.recognizing(this.privTranslationRecognizer, result);
|
||||
/* tslint:disable:no-empty */
|
||||
/* eslint-disable no-empty */
|
||||
} catch (error) {
|
||||
// Not going to let errors in the event handler
|
||||
// trip things up.
|
||||
|
@ -180,7 +179,7 @@ export class TranslationServiceRecognizer extends ServiceRecognizerBase {
|
|||
break;
|
||||
|
||||
case "translation.response":
|
||||
const phrase: { SpeechPhrase: ITranslationPhrase } = JSON.parse(connectionMessage.textBody);
|
||||
const phrase: { SpeechPhrase: ITranslationPhrase } = JSON.parse(connectionMessage.textBody) as { SpeechPhrase: ITranslationPhrase };
|
||||
if (!!phrase.SpeechPhrase) {
|
||||
await handleTranslationPhrase(TranslationPhrase.fromTranslationResponse(phrase));
|
||||
}
|
||||
|
@ -205,7 +204,7 @@ export class TranslationServiceRecognizer extends ServiceRecognizerBase {
|
|||
|
||||
try {
|
||||
this.privTranslationRecognizer.synthesizing(this.privTranslationRecognizer, retEvent);
|
||||
/* tslint:disable:no-empty */
|
||||
/* eslint-disable no-empty */
|
||||
} catch (error) {
|
||||
// Not going to let errors in the event handler
|
||||
// trip things up.
|
||||
|
@ -223,7 +222,7 @@ export class TranslationServiceRecognizer extends ServiceRecognizerBase {
|
|||
|
||||
try {
|
||||
this.privTranslationRecognizer.canceled(this.privTranslationRecognizer, canceledResult);
|
||||
/* tslint:disable:no-empty */
|
||||
/* eslint-disable no-empty */
|
||||
} catch (error) {
|
||||
// Not going to let errors in the event handler
|
||||
// trip things up.
|
||||
|
@ -266,7 +265,7 @@ export class TranslationServiceRecognizer extends ServiceRecognizerBase {
|
|||
|
||||
try {
|
||||
this.privTranslationRecognizer.canceled(this.privTranslationRecognizer, cancelEvent);
|
||||
/* tslint:disable:no-empty */
|
||||
/* eslint-disable no-empty */
|
||||
} catch { }
|
||||
}
|
||||
|
||||
|
@ -283,7 +282,7 @@ export class TranslationServiceRecognizer extends ServiceRecognizerBase {
|
|||
properties);
|
||||
try {
|
||||
this.privSuccessCallback(result);
|
||||
/* tslint:disable:no-empty */
|
||||
/* eslint-disable no-empty */
|
||||
this.privSuccessCallback = undefined;
|
||||
} catch { }
|
||||
}
|
||||
|
@ -335,7 +334,7 @@ export class TranslationServiceRecognizer extends ServiceRecognizerBase {
|
|||
if (!!this.privTranslationRecognizer.synthesizing) {
|
||||
try {
|
||||
this.privTranslationRecognizer.synthesizing(this.privTranslationRecognizer, retEvent);
|
||||
/* tslint:disable:no-empty */
|
||||
/* eslint-disable no-empty */
|
||||
} catch (error) {
|
||||
// Not going to let errors in the event handler
|
||||
// trip things up.
|
||||
|
|
|
@ -14,7 +14,7 @@ const CRLF: string = "\r\n";
|
|||
|
||||
export class WebsocketMessageFormatter implements IWebsocketMessageFormatter {
|
||||
|
||||
public toConnectionMessage = (message: RawWebsocketMessage): Promise<ConnectionMessage> => {
|
||||
public toConnectionMessage(message: RawWebsocketMessage): Promise<ConnectionMessage> {
|
||||
const deferral = new Deferred<ConnectionMessage>();
|
||||
|
||||
try {
|
||||
|
@ -64,13 +64,13 @@ export class WebsocketMessageFormatter implements IWebsocketMessageFormatter {
|
|||
deferral.resolve(new ConnectionMessage(message.messageType, body, headers, message.id));
|
||||
}
|
||||
} catch (e) {
|
||||
deferral.reject(`Error formatting the message. Error: ${e}`);
|
||||
deferral.reject(`Error formatting the message. Error: ${e as string}`);
|
||||
}
|
||||
|
||||
return deferral.promise;
|
||||
}
|
||||
|
||||
public fromConnectionMessage = (message: ConnectionMessage): Promise<RawWebsocketMessage> => {
|
||||
public fromConnectionMessage(message: ConnectionMessage): Promise<RawWebsocketMessage> {
|
||||
const deferral = new Deferred<RawWebsocketMessage>();
|
||||
|
||||
try {
|
||||
|
@ -102,13 +102,13 @@ export class WebsocketMessageFormatter implements IWebsocketMessageFormatter {
|
|||
deferral.resolve(new RawWebsocketMessage(MessageType.Binary, payload, message.id));
|
||||
}
|
||||
} catch (e) {
|
||||
deferral.reject(`Error formatting the message. ${e}`);
|
||||
deferral.reject(`Error formatting the message. ${e as string}`);
|
||||
}
|
||||
|
||||
return deferral.promise;
|
||||
}
|
||||
|
||||
private makeHeaders = (message: ConnectionMessage): string => {
|
||||
private makeHeaders(message: ConnectionMessage): string {
|
||||
let headersString: string = "";
|
||||
|
||||
if (message.headers) {
|
||||
|
@ -122,7 +122,7 @@ export class WebsocketMessageFormatter implements IWebsocketMessageFormatter {
|
|||
return headersString;
|
||||
}
|
||||
|
||||
private parseHeaders = (headersString: string): IStringDictionary<string> => {
|
||||
private parseHeaders(headersString: string): IStringDictionary<string> {
|
||||
const headers: IStringDictionary<string> = {};
|
||||
|
||||
if (headersString) {
|
||||
|
@ -146,7 +146,7 @@ export class WebsocketMessageFormatter implements IWebsocketMessageFormatter {
|
|||
return headers;
|
||||
}
|
||||
|
||||
private stringToArrayBuffer = (str: string): ArrayBuffer => {
|
||||
private stringToArrayBuffer(str: string): ArrayBuffer {
|
||||
const buffer = new ArrayBuffer(str.length);
|
||||
const view = new DataView(buffer);
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// tslint:disable:max-classes-per-file
|
||||
/* eslint-disable max-classes-per-file */
|
||||
|
||||
import { EventType, PlatformEvent } from "./PlatformEvent";
|
||||
|
||||
export class AudioSourceEvent extends PlatformEvent {
|
||||
private privAudioSourceId: string;
|
||||
|
||||
constructor(eventName: string, audioSourceId: string, eventType: EventType = EventType.Info) {
|
||||
public constructor(eventName: string, audioSourceId: string, eventType: EventType = EventType.Info) {
|
||||
super(eventName, eventType);
|
||||
this.privAudioSourceId = audioSourceId;
|
||||
}
|
||||
|
@ -19,19 +19,19 @@ export class AudioSourceEvent extends PlatformEvent {
|
|||
}
|
||||
|
||||
export class AudioSourceInitializingEvent extends AudioSourceEvent {
|
||||
constructor(audioSourceId: string) {
|
||||
public constructor(audioSourceId: string) {
|
||||
super("AudioSourceInitializingEvent", audioSourceId);
|
||||
}
|
||||
}
|
||||
|
||||
export class AudioSourceReadyEvent extends AudioSourceEvent {
|
||||
constructor(audioSourceId: string) {
|
||||
public constructor(audioSourceId: string) {
|
||||
super("AudioSourceReadyEvent", audioSourceId);
|
||||
}
|
||||
}
|
||||
|
||||
export class AudioSourceOffEvent extends AudioSourceEvent {
|
||||
constructor(audioSourceId: string) {
|
||||
public constructor(audioSourceId: string) {
|
||||
super("AudioSourceOffEvent", audioSourceId);
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ export class AudioSourceOffEvent extends AudioSourceEvent {
|
|||
export class AudioSourceErrorEvent extends AudioSourceEvent {
|
||||
private privError: string;
|
||||
|
||||
constructor(audioSourceId: string, error: string) {
|
||||
public constructor(audioSourceId: string, error: string) {
|
||||
super("AudioSourceErrorEvent", audioSourceId, EventType.Error);
|
||||
this.privError = error;
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ export class AudioSourceErrorEvent extends AudioSourceEvent {
|
|||
export class AudioStreamNodeEvent extends AudioSourceEvent {
|
||||
private privAudioNodeId: string;
|
||||
|
||||
constructor(eventName: string, audioSourceId: string, audioNodeId: string) {
|
||||
public constructor(eventName: string, audioSourceId: string, audioNodeId: string) {
|
||||
super(eventName, audioSourceId);
|
||||
this.privAudioNodeId = audioNodeId;
|
||||
}
|
||||
|
@ -63,19 +63,19 @@ export class AudioStreamNodeEvent extends AudioSourceEvent {
|
|||
}
|
||||
|
||||
export class AudioStreamNodeAttachingEvent extends AudioStreamNodeEvent {
|
||||
constructor(audioSourceId: string, audioNodeId: string) {
|
||||
public constructor(audioSourceId: string, audioNodeId: string) {
|
||||
super("AudioStreamNodeAttachingEvent", audioSourceId, audioNodeId);
|
||||
}
|
||||
}
|
||||
|
||||
export class AudioStreamNodeAttachedEvent extends AudioStreamNodeEvent {
|
||||
constructor(audioSourceId: string, audioNodeId: string) {
|
||||
public constructor(audioSourceId: string, audioNodeId: string) {
|
||||
super("AudioStreamNodeAttachedEvent", audioSourceId, audioNodeId);
|
||||
}
|
||||
}
|
||||
|
||||
export class AudioStreamNodeDetachedEvent extends AudioStreamNodeEvent {
|
||||
constructor(audioSourceId: string, audioNodeId: string) {
|
||||
public constructor(audioSourceId: string, audioNodeId: string) {
|
||||
super("AudioStreamNodeDetachedEvent", audioSourceId, audioNodeId);
|
||||
}
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ export class AudioStreamNodeDetachedEvent extends AudioStreamNodeEvent {
|
|||
export class AudioStreamNodeErrorEvent extends AudioStreamNodeEvent {
|
||||
private privError: string;
|
||||
|
||||
constructor(audioSourceId: string, audioNodeId: string, error: string) {
|
||||
public constructor(audioSourceId: string, audioNodeId: string, error: string) {
|
||||
super("AudioStreamNodeErrorEvent", audioSourceId, audioNodeId);
|
||||
this.privError = error;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import {
|
|||
export class BackgroundEvent extends PlatformEvent {
|
||||
private privError: string;
|
||||
|
||||
constructor(error: string) {
|
||||
public constructor(error: string) {
|
||||
super("BackgroundEvent", EventType.Error);
|
||||
this.privError = error;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ export class ChunkedArrayBufferStream extends Stream<ArrayBuffer> {
|
|||
private privNextBufferStartTime: number;
|
||||
private privNextBufferReadyBytes: number;
|
||||
|
||||
constructor(targetChunkSize: number, streamId?: string) {
|
||||
public constructor(targetChunkSize: number, streamId?: string) {
|
||||
super(streamId);
|
||||
this.privTargetChunkSize = targetChunkSize;
|
||||
this.privNextBufferReadyBytes = 0;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// tslint:disable:max-classes-per-file
|
||||
/* eslint-disable max-classes-per-file */
|
||||
|
||||
import { ConnectionMessage } from "./ConnectionMessage";
|
||||
import { IStringDictionary } from "./IDictionary";
|
||||
|
@ -10,7 +10,7 @@ import { EventType, PlatformEvent } from "./PlatformEvent";
|
|||
export class ServiceEvent extends PlatformEvent {
|
||||
private privJsonResult: string;
|
||||
|
||||
constructor(eventName: string, jsonstring: string, eventType: EventType = EventType.Info) {
|
||||
public constructor(eventName: string, jsonstring: string, eventType: EventType = EventType.Info) {
|
||||
super(eventName, eventType);
|
||||
this.privJsonResult = jsonstring;
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ export class ServiceEvent extends PlatformEvent {
|
|||
export class ConnectionEvent extends PlatformEvent {
|
||||
private privConnectionId: string;
|
||||
|
||||
constructor(eventName: string, connectionId: string, eventType: EventType = EventType.Info) {
|
||||
public constructor(eventName: string, connectionId: string, eventType: EventType = EventType.Info) {
|
||||
super(eventName, eventType);
|
||||
this.privConnectionId = connectionId;
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ export class ConnectionStartEvent extends ConnectionEvent {
|
|||
private privUri: string;
|
||||
private privHeaders: IStringDictionary<string>;
|
||||
|
||||
constructor(connectionId: string, uri: string, headers?: IStringDictionary<string>) {
|
||||
public constructor(connectionId: string, uri: string, headers?: IStringDictionary<string>) {
|
||||
super("ConnectionStartEvent", connectionId);
|
||||
this.privUri = uri;
|
||||
this.privHeaders = headers;
|
||||
|
@ -53,7 +53,7 @@ export class ConnectionStartEvent extends ConnectionEvent {
|
|||
}
|
||||
|
||||
export class ConnectionEstablishedEvent extends ConnectionEvent {
|
||||
constructor(connectionId: string, metadata?: IStringDictionary<string>) {
|
||||
public constructor(connectionId: string) {
|
||||
super("ConnectionEstablishedEvent", connectionId);
|
||||
}
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ export class ConnectionClosedEvent extends ConnectionEvent {
|
|||
private privReason: string;
|
||||
private privStatusCode: number;
|
||||
|
||||
constructor(connectionId: string, statusCode: number, reason: string) {
|
||||
public constructor(connectionId: string, statusCode: number, reason: string) {
|
||||
super("ConnectionClosedEvent", connectionId, EventType.Debug);
|
||||
this.privReason = reason;
|
||||
this.privStatusCode = statusCode;
|
||||
|
@ -81,7 +81,7 @@ export class ConnectionErrorEvent extends ConnectionEvent {
|
|||
private readonly privMessage: string;
|
||||
private readonly privType: string;
|
||||
|
||||
constructor(connectionId: string, message: string, type: string) {
|
||||
public constructor(connectionId: string, message: string, type: string) {
|
||||
super("ConnectionErrorEvent", connectionId, EventType.Debug);
|
||||
this.privMessage = message;
|
||||
this.privType = type;
|
||||
|
@ -100,7 +100,7 @@ export class ConnectionEstablishErrorEvent extends ConnectionEvent {
|
|||
private privStatusCode: number;
|
||||
private privReason: string;
|
||||
|
||||
constructor(connectionId: string, statuscode: number, reason: string) {
|
||||
public constructor(connectionId: string, statuscode: number, reason: string) {
|
||||
super("ConnectionEstablishErrorEvent", connectionId, EventType.Error);
|
||||
this.privStatusCode = statuscode;
|
||||
this.privReason = reason;
|
||||
|
@ -119,7 +119,7 @@ export class ConnectionMessageReceivedEvent extends ConnectionEvent {
|
|||
private privNetworkReceivedTime: string;
|
||||
private privMessage: ConnectionMessage;
|
||||
|
||||
constructor(connectionId: string, networkReceivedTimeISO: string, message: ConnectionMessage) {
|
||||
public constructor(connectionId: string, networkReceivedTimeISO: string, message: ConnectionMessage) {
|
||||
super("ConnectionMessageReceivedEvent", connectionId);
|
||||
this.privNetworkReceivedTime = networkReceivedTimeISO;
|
||||
this.privMessage = message;
|
||||
|
@ -138,7 +138,7 @@ export class ConnectionMessageSentEvent extends ConnectionEvent {
|
|||
private privNetworkSentTime: string;
|
||||
private privMessage: ConnectionMessage;
|
||||
|
||||
constructor(connectionId: string, networkSentTimeISO: string, message: ConnectionMessage) {
|
||||
public constructor(connectionId: string, networkSentTimeISO: string, message: ConnectionMessage) {
|
||||
super("ConnectionMessageSentEvent", connectionId);
|
||||
this.privNetworkSentTime = networkSentTimeISO;
|
||||
this.privMessage = message;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
|
@ -34,6 +35,7 @@ export class ConnectionMessage {
|
|||
}
|
||||
|
||||
this.privMessageType = messageType;
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
this.privBody = body;
|
||||
this.privHeaders = headers ? headers : {};
|
||||
this.privId = id ? id : createNoDashGuid();
|
||||
|
|
|
@ -5,7 +5,7 @@ export class ConnectionOpenResponse {
|
|||
private privStatusCode: number;
|
||||
private privReason: string;
|
||||
|
||||
constructor(statusCode: number, reason: string) {
|
||||
public constructor(statusCode: number, reason: string) {
|
||||
this.privStatusCode = statusCode;
|
||||
this.privReason = reason;
|
||||
}
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// tslint:disable:max-classes-per-file
|
||||
/* eslint-disable max-classes-per-file */
|
||||
|
||||
import { AgentConfig } from "../common.speech/Exports";
|
||||
import { EventType, PlatformEvent } from "./PlatformEvent";
|
||||
|
||||
export class DialogEvent extends PlatformEvent {
|
||||
|
||||
constructor(eventName: string, eventType: EventType = EventType.Info) {
|
||||
public constructor(eventName: string, eventType: EventType = EventType.Info) {
|
||||
super(eventName, eventType);
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ export class DialogEvent extends PlatformEvent {
|
|||
export class SendingAgentContextMessageEvent extends DialogEvent {
|
||||
private privAgentConfig: AgentConfig;
|
||||
|
||||
constructor(agentConfig: AgentConfig) {
|
||||
public constructor(agentConfig: AgentConfig) {
|
||||
super("SendingAgentContextMessageEvent");
|
||||
this.privAgentConfig = agentConfig;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// tslint:disable:max-classes-per-file
|
||||
/* eslint-disable max-classes-per-file */
|
||||
|
||||
/**
|
||||
* The error that is thrown when an argument passed in is null.
|
||||
|
@ -56,7 +56,6 @@ export class InvalidOperationError extends Error {
|
|||
* @class ObjectDisposedError
|
||||
* @extends {Error}
|
||||
*/
|
||||
// tslint:disable-next-line:max-classes-per-file
|
||||
export class ObjectDisposedError extends Error {
|
||||
|
||||
/**
|
||||
|
|
|
@ -13,11 +13,11 @@ export class EventSource<TEvent extends PlatformEvent> implements IEventSource<T
|
|||
private privMetadata: IStringDictionary<string>;
|
||||
private privIsDisposed: boolean = false;
|
||||
|
||||
constructor(metadata?: IStringDictionary<string>) {
|
||||
public constructor(metadata?: IStringDictionary<string>) {
|
||||
this.privMetadata = metadata;
|
||||
}
|
||||
|
||||
public onEvent = (event: TEvent): void => {
|
||||
public onEvent(event: TEvent): void {
|
||||
if (this.isDisposed()) {
|
||||
throw (new ObjectDisposedError("EventSource"));
|
||||
}
|
||||
|
@ -41,26 +41,26 @@ export class EventSource<TEvent extends PlatformEvent> implements IEventSource<T
|
|||
}
|
||||
}
|
||||
|
||||
public attach = (onEventCallback: (event: TEvent) => void): IDetachable => {
|
||||
public attach(onEventCallback: (event: TEvent) => void): IDetachable {
|
||||
const id = createNoDashGuid();
|
||||
this.privEventListeners[id] = onEventCallback;
|
||||
return {
|
||||
detach: () => {
|
||||
detach: (): Promise<void> => {
|
||||
delete this.privEventListeners[id];
|
||||
return Promise.resolve();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public attachListener = (listener: IEventListener<TEvent>): IDetachable => {
|
||||
return this.attach(listener.onEvent);
|
||||
public attachListener(listener: IEventListener<TEvent>): IDetachable {
|
||||
return this.attach((e: TEvent): void => listener.onEvent(e));
|
||||
}
|
||||
|
||||
public isDisposed = (): boolean => {
|
||||
public isDisposed(): boolean {
|
||||
return this.privIsDisposed;
|
||||
}
|
||||
|
||||
public dispose = (): void => {
|
||||
public dispose(): void {
|
||||
this.privEventListeners = null;
|
||||
this.privIsDisposed = true;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import { PlatformEvent } from "./PlatformEvent";
|
|||
export class Events {
|
||||
private static privInstance: IEventSource<PlatformEvent> = new EventSource<PlatformEvent>();
|
||||
|
||||
public static setEventSource = (eventSource: IEventSource<PlatformEvent>): void => {
|
||||
public static setEventSource(eventSource: IEventSource<PlatformEvent>): void {
|
||||
if (!eventSource) {
|
||||
throw new ArgumentNullError("eventSource");
|
||||
}
|
||||
|
|
|
@ -3,12 +3,8 @@
|
|||
|
||||
import { v4 as uuid } from "uuid";
|
||||
|
||||
const createGuid: () => string = (): string => {
|
||||
return uuid();
|
||||
};
|
||||
const createGuid: () => string = (): string => uuid();
|
||||
|
||||
const createNoDashGuid: () => string = (): string => {
|
||||
return createGuid().replace(new RegExp("-", "g"), "").toUpperCase();
|
||||
};
|
||||
const createNoDashGuid: () => string = (): string => createGuid().replace(new RegExp("-", "g"), "").toUpperCase();
|
||||
|
||||
export { createGuid, createNoDashGuid };
|
||||
|
|
|
@ -60,25 +60,25 @@ export class List<TItem> implements IList<TItem> {
|
|||
}
|
||||
}
|
||||
|
||||
public get = (itemIndex: number): TItem => {
|
||||
public get(itemIndex: number): TItem {
|
||||
this.throwIfDisposed();
|
||||
return this.privList[itemIndex];
|
||||
}
|
||||
|
||||
public first = (): TItem => {
|
||||
public first(): TItem {
|
||||
return this.get(0);
|
||||
}
|
||||
|
||||
public last = (): TItem => {
|
||||
public last(): TItem {
|
||||
return this.get(this.length() - 1);
|
||||
}
|
||||
|
||||
public add = (item: TItem): void => {
|
||||
public add(item: TItem): void {
|
||||
this.throwIfDisposed();
|
||||
this.insertAt(this.privList.length, item);
|
||||
}
|
||||
|
||||
public insertAt = (index: number, item: TItem): void => {
|
||||
public insertAt(index: number, item: TItem): void {
|
||||
this.throwIfDisposed();
|
||||
if (index === 0) {
|
||||
this.privList.unshift(item);
|
||||
|
@ -90,94 +90,94 @@ export class List<TItem> implements IList<TItem> {
|
|||
this.triggerSubscriptions(this.privAddSubscriptions);
|
||||
}
|
||||
|
||||
public removeFirst = (): TItem => {
|
||||
public removeFirst(): TItem {
|
||||
this.throwIfDisposed();
|
||||
return this.removeAt(0);
|
||||
}
|
||||
|
||||
public removeLast = (): TItem => {
|
||||
public removeLast(): TItem {
|
||||
this.throwIfDisposed();
|
||||
return this.removeAt(this.length() - 1);
|
||||
}
|
||||
|
||||
public removeAt = (index: number): TItem => {
|
||||
public removeAt(index: number): TItem {
|
||||
this.throwIfDisposed();
|
||||
return this.remove(index, 1)[0];
|
||||
}
|
||||
|
||||
public remove = (index: number, count: number): TItem[] => {
|
||||
public remove(index: number, count: number): TItem[] {
|
||||
this.throwIfDisposed();
|
||||
const removedElements = this.privList.splice(index, count);
|
||||
this.triggerSubscriptions(this.privRemoveSubscriptions);
|
||||
return removedElements;
|
||||
}
|
||||
|
||||
public clear = (): void => {
|
||||
public clear(): void {
|
||||
this.throwIfDisposed();
|
||||
this.remove(0, this.length());
|
||||
}
|
||||
|
||||
public length = (): number => {
|
||||
public length(): number {
|
||||
this.throwIfDisposed();
|
||||
return this.privList.length;
|
||||
}
|
||||
|
||||
public onAdded = (addedCallback: () => void): IDetachable => {
|
||||
public onAdded(addedCallback: () => void): IDetachable {
|
||||
this.throwIfDisposed();
|
||||
const subscriptionId = this.privSubscriptionIdCounter++;
|
||||
|
||||
this.privAddSubscriptions[subscriptionId] = addedCallback;
|
||||
|
||||
return {
|
||||
detach: () => {
|
||||
detach: (): Promise<void> => {
|
||||
delete this.privAddSubscriptions[subscriptionId];
|
||||
return Promise.resolve();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public onRemoved = (removedCallback: () => void): IDetachable => {
|
||||
public onRemoved(removedCallback: () => void): IDetachable {
|
||||
this.throwIfDisposed();
|
||||
const subscriptionId = this.privSubscriptionIdCounter++;
|
||||
|
||||
this.privRemoveSubscriptions[subscriptionId] = removedCallback;
|
||||
|
||||
return {
|
||||
detach: () => {
|
||||
detach: (): Promise<void> => {
|
||||
delete this.privRemoveSubscriptions[subscriptionId];
|
||||
return Promise.resolve();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public onDisposed = (disposedCallback: () => void): IDetachable => {
|
||||
public onDisposed(disposedCallback: () => void): IDetachable {
|
||||
this.throwIfDisposed();
|
||||
const subscriptionId = this.privSubscriptionIdCounter++;
|
||||
|
||||
this.privDisposedSubscriptions[subscriptionId] = disposedCallback;
|
||||
|
||||
return {
|
||||
detach: () => {
|
||||
detach: (): Promise<void> => {
|
||||
delete this.privDisposedSubscriptions[subscriptionId];
|
||||
return Promise.resolve();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public join = (seperator?: string): string => {
|
||||
public join(seperator?: string): string {
|
||||
this.throwIfDisposed();
|
||||
return this.privList.join(seperator);
|
||||
}
|
||||
|
||||
public toArray = (): TItem[] => {
|
||||
public toArray(): TItem[] {
|
||||
const cloneCopy = Array<TItem>();
|
||||
this.privList.forEach((val: TItem) => {
|
||||
this.privList.forEach((val: TItem): void => {
|
||||
cloneCopy.push(val);
|
||||
});
|
||||
return cloneCopy;
|
||||
}
|
||||
|
||||
public any = (callback?: (item: TItem, index: number) => boolean): boolean => {
|
||||
public any(callback?: (item: TItem, index: number) => boolean): boolean {
|
||||
this.throwIfDisposed();
|
||||
if (callback) {
|
||||
return this.where(callback).length() > 0;
|
||||
|
@ -186,19 +186,19 @@ export class List<TItem> implements IList<TItem> {
|
|||
}
|
||||
}
|
||||
|
||||
public all = (callback: (item: TItem) => boolean): boolean => {
|
||||
public all(callback: (item: TItem) => boolean): boolean {
|
||||
this.throwIfDisposed();
|
||||
return this.where(callback).length() === this.length();
|
||||
}
|
||||
|
||||
public forEach = (callback: (item: TItem, index: number) => void): void => {
|
||||
public forEach(callback: (item: TItem, index: number) => void): void {
|
||||
this.throwIfDisposed();
|
||||
for (let i = 0; i < this.length(); i++) {
|
||||
callback(this.privList[i], i);
|
||||
}
|
||||
}
|
||||
|
||||
public select = <T2>(callback: (item: TItem, index: number) => T2): List<T2> => {
|
||||
public select<T2>(callback: (item: TItem, index: number) => T2): List<T2> {
|
||||
this.throwIfDisposed();
|
||||
const selectList: T2[] = [];
|
||||
for (let i = 0; i < this.privList.length; i++) {
|
||||
|
@ -208,7 +208,7 @@ export class List<TItem> implements IList<TItem> {
|
|||
return new List<T2>(selectList);
|
||||
}
|
||||
|
||||
public where = (callback: (item: TItem, index: number) => boolean): List<TItem> => {
|
||||
public where(callback: (item: TItem, index: number) => boolean): List<TItem> {
|
||||
this.throwIfDisposed();
|
||||
const filteredList = new List<TItem>();
|
||||
for (let i = 0; i < this.privList.length; i++) {
|
||||
|
@ -219,38 +219,38 @@ export class List<TItem> implements IList<TItem> {
|
|||
return filteredList;
|
||||
}
|
||||
|
||||
public orderBy = (compareFn: (a: TItem, b: TItem) => number): List<TItem> => {
|
||||
public orderBy(compareFn: (a: TItem, b: TItem) => number): List<TItem> {
|
||||
this.throwIfDisposed();
|
||||
const clonedArray = this.toArray();
|
||||
const orderedArray = clonedArray.sort(compareFn);
|
||||
return new List(orderedArray);
|
||||
}
|
||||
|
||||
public orderByDesc = (compareFn: (a: TItem, b: TItem) => number): List<TItem> => {
|
||||
public orderByDesc(compareFn: (a: TItem, b: TItem) => number): List<TItem> {
|
||||
this.throwIfDisposed();
|
||||
return this.orderBy((a: TItem, b: TItem) => compareFn(b, a));
|
||||
return this.orderBy((a: TItem, b: TItem): number => compareFn(b, a));
|
||||
}
|
||||
|
||||
public clone = (): List<TItem> => {
|
||||
public clone(): List<TItem> {
|
||||
this.throwIfDisposed();
|
||||
return new List<TItem>(this.toArray());
|
||||
}
|
||||
|
||||
public concat = (list: List<TItem>): List<TItem> => {
|
||||
public concat(list: List<TItem>): List<TItem> {
|
||||
this.throwIfDisposed();
|
||||
return new List<TItem>(this.privList.concat(list.toArray()));
|
||||
}
|
||||
|
||||
public concatArray = (array: TItem[]): List<TItem> => {
|
||||
public concatArray(array: TItem[]): List<TItem> {
|
||||
this.throwIfDisposed();
|
||||
return new List<TItem>(this.privList.concat(array));
|
||||
}
|
||||
|
||||
public isDisposed = (): boolean => {
|
||||
public isDisposed(): boolean {
|
||||
return this.privList == null;
|
||||
}
|
||||
|
||||
public dispose = (reason?: string): void => {
|
||||
public dispose(reason?: string): void {
|
||||
if (!this.isDisposed()) {
|
||||
this.privDisposeReason = reason;
|
||||
this.privList = null;
|
||||
|
@ -260,13 +260,13 @@ export class List<TItem> implements IList<TItem> {
|
|||
}
|
||||
}
|
||||
|
||||
private throwIfDisposed = (): void => {
|
||||
private throwIfDisposed(): void {
|
||||
if (this.isDisposed()) {
|
||||
throw new ObjectDisposedError("List", this.privDisposeReason);
|
||||
}
|
||||
}
|
||||
|
||||
private triggerSubscriptions = (subscriptions: IStringDictionary<() => void>): void => {
|
||||
private triggerSubscriptions(subscriptions: IStringDictionary<() => void>): void {
|
||||
if (subscriptions) {
|
||||
for (const subscriptionId in subscriptions) {
|
||||
if (subscriptionId) {
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// tslint:disable:max-classes-per-file
|
||||
/* eslint-disable max-classes-per-file */
|
||||
|
||||
import { EventType, PlatformEvent } from "./PlatformEvent";
|
||||
|
||||
export class OCSPEvent extends PlatformEvent {
|
||||
private privSignature: string;
|
||||
|
||||
constructor(eventName: string, eventType: EventType, signature: string) {
|
||||
public constructor(eventName: string, eventType: EventType, signature: string) {
|
||||
super(eventName, eventType);
|
||||
|
||||
this.privSignature = signature;
|
||||
|
@ -16,55 +16,55 @@ export class OCSPEvent extends PlatformEvent {
|
|||
}
|
||||
|
||||
export class OCSPMemoryCacheHitEvent extends OCSPEvent {
|
||||
constructor(signature: string) {
|
||||
public constructor(signature: string) {
|
||||
super("OCSPMemoryCacheHitEvent", EventType.Debug, signature);
|
||||
}
|
||||
}
|
||||
|
||||
export class OCSPCacheMissEvent extends OCSPEvent {
|
||||
constructor(signature: string) {
|
||||
public constructor(signature: string) {
|
||||
super("OCSPCacheMissEvent", EventType.Debug, signature);
|
||||
}
|
||||
}
|
||||
|
||||
export class OCSPDiskCacheHitEvent extends OCSPEvent {
|
||||
constructor(signature: string) {
|
||||
public constructor(signature: string) {
|
||||
super("OCSPDiskCacheHitEvent", EventType.Debug, signature);
|
||||
}
|
||||
}
|
||||
|
||||
export class OCSPCacheUpdateNeededEvent extends OCSPEvent {
|
||||
constructor(signature: string) {
|
||||
public constructor(signature: string) {
|
||||
super("OCSPCacheUpdateNeededEvent", EventType.Debug, signature);
|
||||
}
|
||||
}
|
||||
|
||||
export class OCSPMemoryCacheStoreEvent extends OCSPEvent {
|
||||
constructor(signature: string) {
|
||||
public constructor(signature: string) {
|
||||
super("OCSPMemoryCacheStoreEvent", EventType.Debug, signature);
|
||||
}
|
||||
}
|
||||
|
||||
export class OCSPDiskCacheStoreEvent extends OCSPEvent {
|
||||
constructor(signature: string) {
|
||||
public constructor(signature: string) {
|
||||
super("OCSPDiskCacheStoreEvent", EventType.Debug, signature);
|
||||
}
|
||||
}
|
||||
|
||||
export class OCSPCacheUpdateCompleteEvent extends OCSPEvent {
|
||||
constructor(signature: string) {
|
||||
public constructor(signature: string) {
|
||||
super("OCSPCacheUpdateCompleteEvent", EventType.Debug, signature);
|
||||
}
|
||||
}
|
||||
|
||||
export class OCSPStapleReceivedEvent extends OCSPEvent {
|
||||
constructor() {
|
||||
public constructor() {
|
||||
super("OCSPStapleReceivedEvent", EventType.Debug, "");
|
||||
}
|
||||
}
|
||||
|
||||
export class OCSPWSUpgradeStartedEvent extends OCSPEvent {
|
||||
constructor(serialNumber: string) {
|
||||
public constructor(serialNumber: string) {
|
||||
super("OCSPWSUpgradeStartedEvent", EventType.Debug, serialNumber);
|
||||
}
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ export class OCSPWSUpgradeStartedEvent extends OCSPEvent {
|
|||
export class OCSPCacheEntryExpiredEvent extends OCSPEvent {
|
||||
private privExpireTime: number;
|
||||
|
||||
constructor(serialNumber: string, expireTime: number) {
|
||||
public constructor(serialNumber: string, expireTime: number) {
|
||||
super("OCSPCacheEntryExpiredEvent", EventType.Debug, serialNumber);
|
||||
this.privExpireTime = expireTime;
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ export class OCSPCacheEntryNeedsRefreshEvent extends OCSPEvent {
|
|||
private privExpireTime: number;
|
||||
private privStartTime: number;
|
||||
|
||||
constructor(serialNumber: string, startTime: number, expireTime: number) {
|
||||
public constructor(serialNumber: string, startTime: number, expireTime: number) {
|
||||
super("OCSPCacheEntryNeedsRefreshEvent", EventType.Debug, serialNumber);
|
||||
this.privExpireTime = expireTime;
|
||||
this.privStartTime = startTime;
|
||||
|
@ -95,7 +95,7 @@ export class OCSPCacheHitEvent extends OCSPEvent {
|
|||
private privExpireTimeString: string;
|
||||
private privStartTimeString: string;
|
||||
|
||||
constructor(serialNumber: string, startTime: number, expireTime: number) {
|
||||
public constructor(serialNumber: string, startTime: number, expireTime: number) {
|
||||
super("OCSPCacheHitEvent", EventType.Debug, serialNumber);
|
||||
this.privExpireTime = expireTime;
|
||||
this.privExpireTimeString = new Date(expireTime).toLocaleDateString();
|
||||
|
@ -107,7 +107,7 @@ export class OCSPCacheHitEvent extends OCSPEvent {
|
|||
export class OCSPVerificationFailedEvent extends OCSPEvent {
|
||||
private privError: string;
|
||||
|
||||
constructor(serialNumber: string, error: string) {
|
||||
public constructor(serialNumber: string, error: string) {
|
||||
super("OCSPVerificationFailedEvent", EventType.Debug, serialNumber);
|
||||
this.privError = error;
|
||||
}
|
||||
|
@ -116,14 +116,14 @@ export class OCSPVerificationFailedEvent extends OCSPEvent {
|
|||
export class OCSPCacheFetchErrorEvent extends OCSPEvent {
|
||||
private privError: string;
|
||||
|
||||
constructor(serialNumber: string, error: string) {
|
||||
public constructor(serialNumber: string, error: string) {
|
||||
super("OCSPCacheFetchErrorEvent", EventType.Debug, serialNumber);
|
||||
this.privError = error;
|
||||
}
|
||||
}
|
||||
|
||||
export class OCSPResponseRetrievedEvent extends OCSPEvent {
|
||||
constructor(serialNumber: string) {
|
||||
public constructor(serialNumber: string) {
|
||||
super("OCSPResponseRetrievedEvent", EventType.Debug, serialNumber);
|
||||
}
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ export class OCSPResponseRetrievedEvent extends OCSPEvent {
|
|||
export class OCSPCacheUpdateErrorEvent extends OCSPEvent {
|
||||
private privError: string;
|
||||
|
||||
constructor(serialNumber: string, error: string) {
|
||||
public constructor(serialNumber: string, error: string) {
|
||||
super("OCSPCacheUpdateErrorEvent", EventType.Debug, serialNumber);
|
||||
this.privError = error;
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ export class PlatformEvent {
|
|||
private privEventType: EventType;
|
||||
private privMetadata: IStringDictionary<string>;
|
||||
|
||||
constructor(eventName: string, eventType: EventType) {
|
||||
public constructor(eventName: string, eventType: EventType) {
|
||||
this.privName = eventName;
|
||||
this.privEventId = createNoDashGuid();
|
||||
this.privEventTime = new Date().toISOString();
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// tslint:disable:max-classes-per-file
|
||||
|
||||
import { ArgumentNullError } from "./Error";
|
||||
/* eslint-disable max-classes-per-file, @typescript-eslint/typedef */
|
||||
|
||||
export enum PromiseState {
|
||||
None,
|
||||
|
@ -26,13 +24,13 @@ export class PromiseResult<T> {
|
|||
protected privResult: T;
|
||||
|
||||
public constructor(promiseResultEventSource: PromiseResultEventSource<T>) {
|
||||
promiseResultEventSource.on((result: T) => {
|
||||
promiseResultEventSource.on((result: T): void => {
|
||||
if (!this.privIsCompleted) {
|
||||
this.privIsCompleted = true;
|
||||
this.privIsError = false;
|
||||
this.privResult = result;
|
||||
}
|
||||
}, (error: string) => {
|
||||
}, (error: string): void => {
|
||||
if (!this.privIsCompleted) {
|
||||
this.privIsCompleted = true;
|
||||
this.privIsError = true;
|
||||
|
@ -61,7 +59,7 @@ export class PromiseResult<T> {
|
|||
if (this.isError) {
|
||||
throw this.error;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export class PromiseResultEventSource<T> {
|
||||
|
@ -71,16 +69,16 @@ export class PromiseResultEventSource<T> {
|
|||
|
||||
public setResult = (result: T): void => {
|
||||
this.privOnSetResult(result);
|
||||
}
|
||||
};
|
||||
|
||||
public setError = (error: string): void => {
|
||||
this.privOnSetError(error);
|
||||
}
|
||||
};
|
||||
|
||||
public on = (onSetResult: (result: T) => void, onSetError: (error: string) => void): void => {
|
||||
this.privOnSetResult = onSetResult;
|
||||
this.privOnSetError = onSetError;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export class Deferred<T> implements IDeferred<T> {
|
||||
|
@ -89,6 +87,7 @@ export class Deferred<T> implements IDeferred<T> {
|
|||
private privReject: (reason?: any) => void;
|
||||
|
||||
public constructor() {
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
||||
this.privPromise = new Promise<T>((resolve: (value: T) => void, reject: (reason: any) => void) => {
|
||||
this.privResolve = resolve;
|
||||
this.privReject = reject;
|
||||
|
@ -102,12 +101,12 @@ export class Deferred<T> implements IDeferred<T> {
|
|||
public resolve = (result: T | Promise<T>): Deferred<T> => {
|
||||
this.privResolve(result);
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
public reject = (error: string): Deferred<T> => {
|
||||
this.privReject(error);
|
||||
return this;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export class Sink<T> {
|
||||
|
@ -131,7 +130,7 @@ export class Sink<T> {
|
|||
return this.privPromiseResult;
|
||||
}
|
||||
|
||||
public resolve = (result: T): void => {
|
||||
public resolve(result: T): void {
|
||||
if (this.privState !== PromiseState.None) {
|
||||
throw new Error("'Cannot resolve a completed promise'");
|
||||
}
|
||||
|
@ -146,7 +145,7 @@ export class Sink<T> {
|
|||
this.detachHandlers();
|
||||
}
|
||||
|
||||
public reject = (error: string): void => {
|
||||
public reject(error: string): void {
|
||||
if (this.privState !== PromiseState.None) {
|
||||
throw new Error("'Cannot reject a completed promise'");
|
||||
}
|
||||
|
@ -161,12 +160,13 @@ export class Sink<T> {
|
|||
this.detachHandlers();
|
||||
}
|
||||
|
||||
public on = (
|
||||
public on(
|
||||
successCallback: (result: T) => void,
|
||||
errorCallback: (error: string) => void): void => {
|
||||
errorCallback: (error: string) => void): void {
|
||||
|
||||
if (successCallback == null) {
|
||||
successCallback = (r: T) => { return; };
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
successCallback = (): void => { };
|
||||
}
|
||||
|
||||
if (this.privState === PromiseState.None) {
|
||||
|
@ -183,32 +183,33 @@ export class Sink<T> {
|
|||
}
|
||||
}
|
||||
|
||||
private executeSuccessCallback = (result: T, successCallback: (result: T) => void, errorCallback: (error: string) => void): void => {
|
||||
private executeSuccessCallback(result: T, successCallback: (result: T) => void, errorCallback: (error: string) => void): void {
|
||||
try {
|
||||
successCallback(result);
|
||||
} catch (e) {
|
||||
this.executeErrorCallback(`'Unhandled callback error: ${e}'`, errorCallback);
|
||||
this.executeErrorCallback(`'Unhandled callback error: ${e as string}'`, errorCallback);
|
||||
}
|
||||
}
|
||||
|
||||
private executeErrorCallback = (error: string, errorCallback: (error: string) => void): void => {
|
||||
private executeErrorCallback(error: string, errorCallback: (error: string) => void): void {
|
||||
if (errorCallback) {
|
||||
try {
|
||||
errorCallback(error);
|
||||
} catch (e) {
|
||||
throw new Error(`'Unhandled callback error: ${e}. InnerError: ${error}'`);
|
||||
throw new Error(`'Unhandled callback error: ${e as string}. InnerError: ${error}'`);
|
||||
}
|
||||
} else {
|
||||
throw new Error(`'Unhandled error: ${error}'`);
|
||||
}
|
||||
}
|
||||
|
||||
private detachHandlers = (): void => {
|
||||
private detachHandlers(): void {
|
||||
this.privErrorHandlers = [];
|
||||
this.privSuccessHandlers = [];
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line prefer-arrow/prefer-arrow-functions
|
||||
export function marshalPromiseToCallbacks<T>(
|
||||
promise: Promise<T>,
|
||||
cb?: (value: T) => void,
|
||||
|
@ -222,12 +223,12 @@ export function marshalPromiseToCallbacks<T>(
|
|||
if (!!err) {
|
||||
try {
|
||||
if (error instanceof Error) {
|
||||
const typedError: Error = error as Error;
|
||||
const typedError: Error = error ;
|
||||
err(typedError.name + ": " + typedError.message);
|
||||
} else {
|
||||
err(error);
|
||||
err(error as string);
|
||||
}
|
||||
/* tslint:disable:no-empty */
|
||||
// eslint-disable-next-line no-empty
|
||||
} catch (error) { }
|
||||
}
|
||||
}
|
||||
|
@ -235,12 +236,12 @@ export function marshalPromiseToCallbacks<T>(
|
|||
if (!!err) {
|
||||
try {
|
||||
if (error instanceof Error) {
|
||||
const typedError: Error = error as Error;
|
||||
const typedError: Error = error;
|
||||
err(typedError.name + ": " + typedError.message);
|
||||
} else {
|
||||
err(error);
|
||||
err(error as string);
|
||||
}
|
||||
/* tslint:disable:no-empty */
|
||||
// eslint-disable-next-line no-empty
|
||||
} catch (error) { }
|
||||
}
|
||||
});
|
||||
|
|
|
@ -25,7 +25,7 @@ export class Queue<TItem> implements IQueue<TItem> {
|
|||
private privPromiseStore: List<Promise<TItem>> = new List<Promise<TItem>>();
|
||||
private privList: List<TItem>;
|
||||
private privDetachables: IDetachable[];
|
||||
private privSubscribers: List<{ type: SubscriberType, deferral: Deferred<TItem> }>;
|
||||
private privSubscribers: List<{ type: SubscriberType; deferral: Deferred<TItem> }>;
|
||||
private privIsDrainInProgress: boolean = false;
|
||||
private privIsDisposing: boolean = false;
|
||||
private privDisposeReason: string = null;
|
||||
|
@ -33,24 +33,24 @@ export class Queue<TItem> implements IQueue<TItem> {
|
|||
public constructor(list?: List<TItem>) {
|
||||
this.privList = list ? list : new List<TItem>();
|
||||
this.privDetachables = [];
|
||||
this.privSubscribers = new List<{ type: SubscriberType, deferral: Deferred<TItem> }>();
|
||||
this.privDetachables.push(this.privList.onAdded(this.drain));
|
||||
this.privSubscribers = new List<{ type: SubscriberType; deferral: Deferred<TItem> }>();
|
||||
this.privDetachables.push(this.privList.onAdded((): void => this.drain()));
|
||||
}
|
||||
|
||||
public enqueue = (item: TItem): void => {
|
||||
public enqueue(item: TItem): void {
|
||||
this.throwIfDispose();
|
||||
this.enqueueFromPromise(new Promise<TItem>((resolve: (value: TItem) => void, reject: (reason: any) => void) => { resolve(item); }));
|
||||
this.enqueueFromPromise(new Promise<TItem>((resolve: (value: TItem) => void): void => resolve(item)));
|
||||
}
|
||||
|
||||
public enqueueFromPromise = (promise: Promise<TItem>): void => {
|
||||
public enqueueFromPromise(promise: Promise<TItem>): void {
|
||||
this.throwIfDispose();
|
||||
promise.then((val: TItem): void => {
|
||||
this.privList.add(val);
|
||||
/* tslint:disable:no-empty */
|
||||
}, (error: string): void => { });
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
}, (): void => { });
|
||||
}
|
||||
|
||||
public dequeue = (): Promise<TItem> => {
|
||||
public dequeue(): Promise<TItem> {
|
||||
this.throwIfDispose();
|
||||
const deferredSubscriber = new Deferred<TItem>();
|
||||
|
||||
|
@ -62,7 +62,7 @@ export class Queue<TItem> implements IQueue<TItem> {
|
|||
return deferredSubscriber.promise;
|
||||
}
|
||||
|
||||
public peek = (): Promise<TItem> => {
|
||||
public peek(): Promise<TItem> {
|
||||
this.throwIfDispose();
|
||||
const deferredSubscriber = new Deferred<TItem>();
|
||||
|
||||
|
@ -75,12 +75,12 @@ export class Queue<TItem> implements IQueue<TItem> {
|
|||
return deferredSubscriber.promise;
|
||||
}
|
||||
|
||||
public length = (): number => {
|
||||
public length(): number {
|
||||
this.throwIfDispose();
|
||||
return this.privList.length();
|
||||
}
|
||||
|
||||
public isDisposed = (): boolean => {
|
||||
public isDisposed(): boolean {
|
||||
return this.privSubscribers == null;
|
||||
}
|
||||
|
||||
|
@ -119,12 +119,12 @@ export class Queue<TItem> implements IQueue<TItem> {
|
|||
if (this.privPromiseStore.length() > 0 && pendingItemProcessor) {
|
||||
const promiseArray: Promise<TItem>[] = [];
|
||||
|
||||
this.privPromiseStore.toArray().forEach((wrapper: Promise<TItem>) => {
|
||||
this.privPromiseStore.toArray().forEach((wrapper: Promise<TItem>): void => {
|
||||
promiseArray.push(wrapper);
|
||||
});
|
||||
return Promise.all(promiseArray).finally(() => {
|
||||
return Promise.all(promiseArray).finally((): void => {
|
||||
this.privSubscribers = null;
|
||||
this.privList.forEach((item: TItem, index: number): void => {
|
||||
this.privList.forEach((item: TItem): void => {
|
||||
pendingItemProcessor(item);
|
||||
});
|
||||
this.privList = null;
|
||||
|
@ -141,7 +141,7 @@ export class Queue<TItem> implements IQueue<TItem> {
|
|||
await this.drainAndDispose(null, reason);
|
||||
}
|
||||
|
||||
private drain = (): void => {
|
||||
private drain(): void {
|
||||
if (!this.privIsDrainInProgress && !this.privIsDisposing) {
|
||||
this.privIsDrainInProgress = true;
|
||||
|
||||
|
@ -189,7 +189,7 @@ export class Queue<TItem> implements IQueue<TItem> {
|
|||
}
|
||||
}
|
||||
|
||||
private throwIfDispose = (): void => {
|
||||
private throwIfDispose(): void {
|
||||
if (this.isDisposed()) {
|
||||
if (this.privDisposeReason) {
|
||||
throw new InvalidOperationError(this.privDisposeReason);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
|
@ -15,6 +16,7 @@ export class RawWebsocketMessage {
|
|||
throw new ArgumentNullError("payload");
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
if (messageType === MessageType.Binary && payload.__proto__.constructor.name !== "ArrayBuffer") {
|
||||
throw new InvalidOperationError("Payload must be ArrayBuffer");
|
||||
}
|
||||
|
@ -33,6 +35,7 @@ export class RawWebsocketMessage {
|
|||
}
|
||||
|
||||
public get payload(): any {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||
return this.privPayload;
|
||||
}
|
||||
|
||||
|
@ -49,7 +52,7 @@ export class RawWebsocketMessage {
|
|||
throw new InvalidOperationError("Not supported for text message");
|
||||
}
|
||||
|
||||
return this.privPayload;
|
||||
return this.privPayload as ArrayBuffer;
|
||||
}
|
||||
|
||||
public get id(): string {
|
||||
|
|
|
@ -11,8 +11,7 @@ export class RiffPcmEncoder {
|
|||
this.privDesiredSampleRate = desiredSampleRate;
|
||||
}
|
||||
|
||||
public encode = (
|
||||
actualAudioFrame: Float32Array): ArrayBuffer => {
|
||||
public encode(actualAudioFrame: Float32Array): ArrayBuffer {
|
||||
|
||||
const audioFrame = this.downSampleAudioFrame(actualAudioFrame, this.privActualSampleRate, this.privDesiredSampleRate);
|
||||
|
||||
|
@ -29,23 +28,23 @@ export class RiffPcmEncoder {
|
|||
return buffer;
|
||||
}
|
||||
|
||||
private setString = (view: DataView, offset: number, str: string): void => {
|
||||
private setString(view: DataView, offset: number, str: string): void {
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
view.setUint8(offset + i, str.charCodeAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
private floatTo16BitPCM = (view: DataView, offset: number, input: Float32Array): void => {
|
||||
private floatTo16BitPCM(view: DataView, offset: number, input: Float32Array): void {
|
||||
for (let i = 0; i < input.length; i++ , offset += 2) {
|
||||
const s = Math.max(-1, Math.min(1, input[i]));
|
||||
view.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true);
|
||||
}
|
||||
}
|
||||
|
||||
private downSampleAudioFrame = (
|
||||
private downSampleAudioFrame(
|
||||
srcFrame: Float32Array,
|
||||
srcRate: number,
|
||||
dstRate: number): Float32Array => {
|
||||
dstRate: number): Float32Array {
|
||||
|
||||
if (!srcFrame) {
|
||||
return null;
|
||||
|
|
|
@ -56,14 +56,14 @@ export class Stream<TBuffer> {
|
|||
}
|
||||
}
|
||||
|
||||
public read = (): Promise<IStreamChunk<TBuffer>> => {
|
||||
public read(): Promise<IStreamChunk<TBuffer>> {
|
||||
if (this.privIsReadEnded) {
|
||||
throw new InvalidOperationError("Stream read has already finished");
|
||||
}
|
||||
|
||||
return this.privReaderQueue
|
||||
.dequeue()
|
||||
.then(async (streamChunk: IStreamChunk<TBuffer>) => {
|
||||
.then(async (streamChunk: IStreamChunk<TBuffer>): Promise<IStreamChunk<TBuffer>> => {
|
||||
if (streamChunk === undefined || streamChunk.isEnd) {
|
||||
await this.privReaderQueue.dispose("End of stream reached");
|
||||
}
|
||||
|
@ -71,14 +71,14 @@ export class Stream<TBuffer> {
|
|||
return streamChunk;
|
||||
});
|
||||
}
|
||||
public readEnded = (): void => {
|
||||
public readEnded(): void {
|
||||
if (!this.privIsReadEnded) {
|
||||
this.privIsReadEnded = true;
|
||||
this.privReaderQueue = new Queue<IStreamChunk<TBuffer>>();
|
||||
}
|
||||
}
|
||||
|
||||
private throwIfClosed = (): void => {
|
||||
private throwIfClosed(): void {
|
||||
if (this.privIsWriteEnded) {
|
||||
throw new InvalidOperationError("Stream closed");
|
||||
}
|
||||
|
|
|
@ -65,18 +65,18 @@ export class Timeout {
|
|||
|
||||
private static workerTimers: null | IWorkerTimers = null;
|
||||
|
||||
public static clearTimeout: IWorkerTimers["clearTimeout"] = (timerId) => Timeout.timers().clearTimeout(timerId);
|
||||
public static clearTimeout: IWorkerTimers["clearTimeout"] = (timerId: number): void => Timeout.timers().clearTimeout(timerId);
|
||||
|
||||
public static setTimeout: IWorkerTimers["setTimeout"] = (func, delay) => Timeout.timers().setTimeout(func, delay);
|
||||
public static setTimeout: IWorkerTimers["setTimeout"] = (func: () => any, delay: number): number => Timeout.timers().setTimeout(func, delay);
|
||||
|
||||
public static load = (url: string) => {
|
||||
public static load(url: string): any {
|
||||
// Prefilling the Maps with a function indexed by zero is necessary to be compliant with the specification.
|
||||
const scheduledTimeoutFunctions: Map<number, number | Func> = new Map([[0, () => { }]]); // tslint:disable-line no-empty
|
||||
const scheduledTimeoutFunctions: Map<number, number | Func> = new Map([[0, (): void => { }]]); // eslint-disable-line @typescript-eslint/no-empty-function
|
||||
const unhandledRequests: Map<number, number> = new Map();
|
||||
|
||||
const worker = new Worker(url);
|
||||
|
||||
worker.addEventListener("message", ({ data }: IWorkerEvent) => {
|
||||
worker.addEventListener("message", ({ data }: IWorkerEvent): void => {
|
||||
if (Timeout.isCallNotification(data)) {
|
||||
const {
|
||||
params: { timerId }
|
||||
|
@ -122,7 +122,7 @@ export class Timeout {
|
|||
}
|
||||
});
|
||||
|
||||
const clearTimeout = (timerId: number) => {
|
||||
const clearTimeout = (timerId: number): void => {
|
||||
const id = Math.random();
|
||||
|
||||
unhandledRequests.set(id, timerId);
|
||||
|
@ -135,7 +135,7 @@ export class Timeout {
|
|||
} as IClearRequest);
|
||||
};
|
||||
|
||||
const setTimeout = (func: () => void, delay: number) => {
|
||||
const setTimeout = (func: () => void, delay: number): number => {
|
||||
const timerId = Math.random();
|
||||
|
||||
scheduledTimeoutFunctions.set(timerId, func);
|
||||
|
@ -159,9 +159,10 @@ export class Timeout {
|
|||
};
|
||||
}
|
||||
|
||||
private static loadWorkerTimers = () => {
|
||||
const worker = `!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=14)}([function(e,t,n){"use strict";n.d(t,"a",(function(){return i})),n.d(t,"b",(function(){return u})),n.d(t,"c",(function(){return a})),n.d(t,"d",(function(){return d}));const r=new Map,o=new Map,i=e=>{const t=r.get(e);if(void 0===t)throw new Error('There is no interval scheduled with the given id "'.concat(e,'".'));clearTimeout(t),r.delete(e)},u=e=>{const t=o.get(e);if(void 0===t)throw new Error('There is no timeout scheduled with the given id "'.concat(e,'".'));clearTimeout(t),o.delete(e)},f=(e,t)=>{let n,r;if("performance"in self){const o=performance.now();n=o,r=e-Math.max(0,o-t)}else n=Date.now(),r=e;return{expected:n+r,remainingDelay:r}},c=(e,t,n,r)=>{const o="performance"in self?performance.now():Date.now();o>n?postMessage({id:null,method:"call",params:{timerId:t}}):e.set(t,setTimeout(c,n-o,e,t,n))},a=(e,t,n)=>{const{expected:o,remainingDelay:i}=f(e,n);r.set(t,setTimeout(c,i,r,t,o))},d=(e,t,n)=>{const{expected:r,remainingDelay:i}=f(e,n);o.set(t,setTimeout(c,i,o,t,r))}},function(e,t,n){"use strict";n.r(t);var r=n(2);for(var o in r)"default"!==o&&function(e){n.d(t,e,(function(){return r[e]}))}(o);var i=n(3);for(var o in i)"default"!==o&&function(e){n.d(t,e,(function(){return i[e]}))}(o);var u=n(4);for(var o in u)"default"!==o&&function(e){n.d(t,e,(function(){return u[e]}))}(o);var f=n(5);for(var o in f)"default"!==o&&function(e){n.d(t,e,(function(){return f[e]}))}(o);var c=n(6);for(var o in c)"default"!==o&&function(e){n.d(t,e,(function(){return c[e]}))}(o);var a=n(7);for(var o in a)"default"!==o&&function(e){n.d(t,e,(function(){return a[e]}))}(o);var d=n(8);for(var o in d)"default"!==o&&function(e){n.d(t,e,(function(){return d[e]}))}(o);var s=n(9);for(var o in s)"default"!==o&&function(e){n.d(t,e,(function(){return s[e]}))}(o)},function(e,t){},function(e,t){},function(e,t){},function(e,t){},function(e,t){},function(e,t){},function(e,t){},function(e,t){},function(e,t,n){"use strict";n.r(t);var r=n(11);for(var o in r)"default"!==o&&function(e){n.d(t,e,(function(){return r[e]}))}(o);var i=n(12);for(var o in i)"default"!==o&&function(e){n.d(t,e,(function(){return i[e]}))}(o);var u=n(13);for(var o in u)"default"!==o&&function(e){n.d(t,e,(function(){return u[e]}))}(o)},function(e,t){},function(e,t){},function(e,t){},function(e,t,n){"use strict";n.r(t);var r=n(0),o=n(1);for(var i in o)"default"!==i&&function(e){n.d(t,e,(function(){return o[e]}))}(i);var u=n(10);for(var i in u)"default"!==i&&function(e){n.d(t,e,(function(){return u[e]}))}(i);addEventListener("message",({data:e})=>{try{if("clear"===e.method){const{id:t,params:{timerId:n}}=e;Object(r.b)(n),postMessage({error:null,id:t})}else{if("set"!==e.method)throw new Error('The given method "'.concat(e.method,'" is not supported'));{const{params:{delay:t,now:n,timerId:o}}=e;Object(r.d)(t,o,n)}}}catch(t){postMessage({error:{message:t.message},id:e.id,result:null})}})}]);`; // tslint:disable-line:max-line-length
|
||||
return () => {
|
||||
private static loadWorkerTimers(): () => IWorkerTimers {
|
||||
// eslint-disable-next-line
|
||||
const worker = `!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=14)}([function(e,t,n){"use strict";n.d(t,"a",(function(){return i})),n.d(t,"b",(function(){return u})),n.d(t,"c",(function(){return a})),n.d(t,"d",(function(){return d}));const r=new Map,o=new Map,i=e=>{const t=r.get(e);if(void 0===t)throw new Error('There is no interval scheduled with the given id "'.concat(e,'".'));clearTimeout(t),r.delete(e)},u=e=>{const t=o.get(e);if(void 0===t)throw new Error('There is no timeout scheduled with the given id "'.concat(e,'".'));clearTimeout(t),o.delete(e)},f=(e,t)=>{let n,r;if("performance"in self){const o=performance.now();n=o,r=e-Math.max(0,o-t)}else n=Date.now(),r=e;return{expected:n+r,remainingDelay:r}},c=(e,t,n,r)=>{const o="performance"in self?performance.now():Date.now();o>n?postMessage({id:null,method:"call",params:{timerId:t}}):e.set(t,setTimeout(c,n-o,e,t,n))},a=(e,t,n)=>{const{expected:o,remainingDelay:i}=f(e,n);r.set(t,setTimeout(c,i,r,t,o))},d=(e,t,n)=>{const{expected:r,remainingDelay:i}=f(e,n);o.set(t,setTimeout(c,i,o,t,r))}},function(e,t,n){"use strict";n.r(t);var r=n(2);for(var o in r)"default"!==o&&function(e){n.d(t,e,(function(){return r[e]}))}(o);var i=n(3);for(var o in i)"default"!==o&&function(e){n.d(t,e,(function(){return i[e]}))}(o);var u=n(4);for(var o in u)"default"!==o&&function(e){n.d(t,e,(function(){return u[e]}))}(o);var f=n(5);for(var o in f)"default"!==o&&function(e){n.d(t,e,(function(){return f[e]}))}(o);var c=n(6);for(var o in c)"default"!==o&&function(e){n.d(t,e,(function(){return c[e]}))}(o);var a=n(7);for(var o in a)"default"!==o&&function(e){n.d(t,e,(function(){return a[e]}))}(o);var d=n(8);for(var o in d)"default"!==o&&function(e){n.d(t,e,(function(){return d[e]}))}(o);var s=n(9);for(var o in s)"default"!==o&&function(e){n.d(t,e,(function(){return s[e]}))}(o)},function(e,t){},function(e,t){},function(e,t){},function(e,t){},function(e,t){},function(e,t){},function(e,t){},function(e,t){},function(e,t,n){"use strict";n.r(t);var r=n(11);for(var o in r)"default"!==o&&function(e){n.d(t,e,(function(){return r[e]}))}(o);var i=n(12);for(var o in i)"default"!==o&&function(e){n.d(t,e,(function(){return i[e]}))}(o);var u=n(13);for(var o in u)"default"!==o&&function(e){n.d(t,e,(function(){return u[e]}))}(o)},function(e,t){},function(e,t){},function(e,t){},function(e,t,n){"use strict";n.r(t);var r=n(0),o=n(1);for(var i in o)"default"!==i&&function(e){n.d(t,e,(function(){return o[e]}))}(i);var u=n(10);for(var i in u)"default"!==i&&function(e){n.d(t,e,(function(){return u[e]}))}(i);addEventListener("message",({data:e})=>{try{if("clear"===e.method){const{id:t,params:{timerId:n}}=e;Object(r.b)(n),postMessage({error:null,id:t})}else{if("set"!==e.method)throw new Error('The given method "'.concat(e.method,'" is not supported'));{const{params:{delay:t,now:n,timerId:o}}=e;Object(r.d)(t,o,n)}}}catch(t){postMessage({error:{message:t.message},id:e.id,result:null})}})}]);`;
|
||||
return (): IWorkerTimers => {
|
||||
if (Timeout.workerTimers !== null) {
|
||||
return Timeout.workerTimers;
|
||||
}
|
||||
|
@ -169,22 +170,22 @@ export class Timeout {
|
|||
const blob = new Blob([worker], { type: "application/javascript; charset=utf-8" });
|
||||
const url = URL.createObjectURL(blob);
|
||||
|
||||
Timeout.workerTimers = Timeout.load(url);
|
||||
Timeout.workerTimers = Timeout.load(url) as IWorkerTimers;
|
||||
|
||||
// Edge doesn't like the URL to be revoked directly.
|
||||
Timeout.workerTimers.setTimeout(() => URL.revokeObjectURL(url), 0);
|
||||
Timeout.workerTimers.setTimeout((): void => URL.revokeObjectURL(url), 0);
|
||||
|
||||
return Timeout.workerTimers as IWorkerTimers;
|
||||
return Timeout.workerTimers;
|
||||
};
|
||||
}
|
||||
|
||||
public static timers: () => IWorkerTimers = Timeout.loadWorkerTimers();
|
||||
|
||||
private static isCallNotification = (message: TWorkerMessage): message is ICallNotification => {
|
||||
private static isCallNotification(message: TWorkerMessage): message is ICallNotification {
|
||||
return (message as ICallNotification).method !== undefined && (message as ICallNotification).method === "call";
|
||||
}
|
||||
|
||||
private static isClearResponse = (message: TWorkerMessage): message is IClearResponse => {
|
||||
private static isClearResponse(message: TWorkerMessage): message is IClearResponse {
|
||||
return (message as IClearResponse).error === null && typeof message.id === "number";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,20 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
/* eslint-disable max-classes-per-file */
|
||||
import { PullAudioOutputStream } from "./Audio/AudioOutputStream";
|
||||
|
||||
export interface IActivity {
|
||||
type?: string;
|
||||
speak?: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines contents of received message/events.
|
||||
* @class ActivityReceivedEventArgs
|
||||
*/
|
||||
export class ActivityReceivedEventArgs {
|
||||
private privActivity: any;
|
||||
private privActivity: IActivity;
|
||||
private privAudioStream: PullAudioOutputStream;
|
||||
|
||||
/**
|
||||
|
@ -17,7 +23,7 @@ export class ActivityReceivedEventArgs {
|
|||
* @param {any} activity - The activity..
|
||||
*/
|
||||
public constructor(activity: any, audioStream?: PullAudioOutputStream) {
|
||||
this.privActivity = activity;
|
||||
this.privActivity = activity as IActivity;
|
||||
this.privAudioStream = audioStream;
|
||||
}
|
||||
|
||||
|
@ -28,7 +34,7 @@ export class ActivityReceivedEventArgs {
|
|||
* @public
|
||||
* @returns {any} the received activity.
|
||||
*/
|
||||
public get activity(): any {
|
||||
public get activity(): IActivity {
|
||||
return this.privActivity;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// tslint:disable:max-classes-per-file
|
||||
/* eslint-disable max-classes-per-file */
|
||||
|
||||
import { PathLike } from "fs";
|
||||
import {
|
||||
|
@ -12,7 +12,6 @@ import {
|
|||
import { ISpeechConfigAudioDevice } from "../../common.speech/Exports";
|
||||
import {
|
||||
AudioSourceEvent,
|
||||
Deferred,
|
||||
EventSource,
|
||||
IAudioDestination,
|
||||
IAudioSource,
|
||||
|
@ -24,8 +23,6 @@ import {
|
|||
AudioOutputStream,
|
||||
AudioStreamFormat,
|
||||
IPlayer,
|
||||
PropertyCollection,
|
||||
PropertyId,
|
||||
PullAudioInputStreamCallback,
|
||||
PullAudioOutputStream,
|
||||
PushAudioOutputStream,
|
||||
|
@ -61,7 +58,7 @@ export abstract class AudioConfig {
|
|||
* @function
|
||||
* @public
|
||||
* @param {string | undefined} deviceId - Specifies the device ID of the microphone to be used.
|
||||
* Default microphone is used the value is omitted.
|
||||
* Default microphone is used the value is omitted.
|
||||
* @returns {AudioConfig} The audio input configuration being created.
|
||||
*/
|
||||
public static fromMicrophoneInput(deviceId?: string): AudioConfig {
|
||||
|
@ -87,13 +84,13 @@ export abstract class AudioConfig {
|
|||
* @function
|
||||
* @public
|
||||
* @param {AudioInputStream | PullAudioInputStreamCallback | MediaStream} audioStream - Specifies the custom audio input
|
||||
* stream. Currently, only WAV / PCM is supported.
|
||||
* stream. Currently, only WAV / PCM is supported.
|
||||
* @returns {AudioConfig} The audio input configuration being created.
|
||||
*/
|
||||
public static fromStreamInput(audioStream: AudioInputStream | PullAudioInputStreamCallback
|
||||
| MediaStream): AudioConfig {
|
||||
if (audioStream instanceof PullAudioInputStreamCallback) {
|
||||
return new AudioConfigImpl(new PullAudioInputStreamImpl(audioStream as PullAudioInputStreamCallback));
|
||||
return new AudioConfigImpl(new PullAudioInputStreamImpl(audioStream));
|
||||
}
|
||||
|
||||
if (audioStream instanceof AudioInputStream) {
|
||||
|
@ -134,7 +131,7 @@ export abstract class AudioConfig {
|
|||
return AudioConfig.fromDefaultSpeakerOutput();
|
||||
}
|
||||
if (player instanceof SpeakerAudioDestination) {
|
||||
return new AudioOutputConfigImpl(player as SpeakerAudioDestination);
|
||||
return new AudioOutputConfigImpl(player);
|
||||
}
|
||||
|
||||
throw new Error("Not Supported Type");
|
||||
|
@ -159,13 +156,13 @@ export abstract class AudioConfig {
|
|||
* @function
|
||||
* @public
|
||||
* @param {AudioOutputStream | PushAudioOutputStreamCallback} audioStream - Specifies the custom audio output
|
||||
* stream.
|
||||
* stream.
|
||||
* @returns {AudioConfig} The audio output configuration being created.
|
||||
* Added in version 1.11.0
|
||||
*/
|
||||
public static fromStreamOutput(audioStream: AudioOutputStream | PushAudioOutputStreamCallback): AudioConfig {
|
||||
if (audioStream instanceof PushAudioOutputStreamCallback) {
|
||||
return new AudioOutputConfigImpl(new PushAudioOutputStreamImpl(audioStream as PushAudioOutputStreamCallback));
|
||||
return new AudioOutputConfigImpl(new PushAudioOutputStreamImpl(audioStream));
|
||||
}
|
||||
|
||||
if (audioStream instanceof PushAudioOutputStream) {
|
||||
|
@ -241,11 +238,11 @@ export class AudioConfigImpl extends AudioConfig implements IAudioSource {
|
|||
* @public
|
||||
*/
|
||||
public close(cb?: () => void, err?: (error: string) => void): void {
|
||||
this.privSource.turnOff().then(() => {
|
||||
this.privSource.turnOff().then((): void => {
|
||||
if (!!cb) {
|
||||
cb();
|
||||
}
|
||||
}, (error: string) => {
|
||||
}, (error: string): void => {
|
||||
if (!!err) {
|
||||
err(error);
|
||||
}
|
||||
|
@ -376,11 +373,11 @@ export class AudioOutputConfigImpl extends AudioConfig implements IAudioDestinat
|
|||
return this.privDestination.id();
|
||||
}
|
||||
|
||||
public setProperty(name: string, value: string): void {
|
||||
public setProperty(): void {
|
||||
throw new Error("This AudioConfig instance does not support setting properties.");
|
||||
}
|
||||
|
||||
public getProperty(name: string, def?: string): string {
|
||||
public getProperty(): string {
|
||||
throw new Error("This AudioConfig instance does not support getting properties.");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ export class AudioFileWriter implements IAudioDestination {
|
|||
|
||||
public close(): void {
|
||||
if (this.privFd !== undefined) {
|
||||
this.privWriteStream.on("finish", () => {
|
||||
this.privWriteStream.on("finish", (): void => {
|
||||
if (this.privAudioFormat.hasHeader) {
|
||||
this.privAudioFormat.updateHeader(this.privWriteStream.bytesWritten);
|
||||
fs.writeSync(this.privFd,
|
||||
|
@ -55,7 +55,7 @@ export class AudioFileWriter implements IAudioDestination {
|
|||
}
|
||||
}
|
||||
|
||||
public id = (): string => {
|
||||
public id(): string {
|
||||
return this.privId;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// tslint:disable:max-classes-per-file
|
||||
/* eslint-disable max-classes-per-file */
|
||||
|
||||
import {
|
||||
connectivity,
|
||||
|
@ -16,7 +16,6 @@ import {
|
|||
AudioStreamNodeAttachingEvent,
|
||||
AudioStreamNodeDetachedEvent,
|
||||
ChunkedArrayBufferStream,
|
||||
Deferred,
|
||||
Events,
|
||||
EventSource,
|
||||
IAudioSource,
|
||||
|
@ -38,7 +37,9 @@ export abstract class AudioInputStream {
|
|||
* Creates and initializes an instance.
|
||||
* @constructor
|
||||
*/
|
||||
protected constructor() { }
|
||||
protected constructor() {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a memory backed PushAudioInputStream with the specified audio format.
|
||||
|
@ -46,7 +47,7 @@ export abstract class AudioInputStream {
|
|||
* @function
|
||||
* @public
|
||||
* @param {AudioStreamFormat} format - The audio data format in which audio will be
|
||||
* written to the push audio stream's write() method (Required if format is not 16 kHz 16bit mono PCM).
|
||||
* written to the push audio stream's write() method (Required if format is not 16 kHz 16bit mono PCM).
|
||||
* @returns {PushAudioInputStream} The audio input stream being created.
|
||||
*/
|
||||
public static createPushStream(format?: AudioStreamFormat): PushAudioInputStream {
|
||||
|
@ -60,9 +61,9 @@ export abstract class AudioInputStream {
|
|||
* @function
|
||||
* @public
|
||||
* @param {PullAudioInputStreamCallback} callback - The custom audio input object, derived from
|
||||
* PullAudioInputStreamCallback
|
||||
* PullAudioInputStreamCallback
|
||||
* @param {AudioStreamFormat} format - The audio data format in which audio will be returned from
|
||||
* the callback's read() method (Required if format is not 16 kHz 16bit mono PCM).
|
||||
* the callback's read() method (Required if format is not 16 kHz 16bit mono PCM).
|
||||
* @returns {PullAudioInputStream} The audio input stream being created.
|
||||
*/
|
||||
public static createPullStream(callback: PullAudioInputStreamCallback, format?: AudioStreamFormat): PullAudioInputStream {
|
||||
|
@ -91,7 +92,7 @@ export abstract class PushAudioInputStream extends AudioInputStream {
|
|||
* @function
|
||||
* @public
|
||||
* @param {AudioStreamFormat} format - The audio data format in which audio will be written to the
|
||||
* push audio stream's write() method (Required if format is not 16 kHz 16bit mono PCM).
|
||||
* push audio stream's write() method (Required if format is not 16 kHz 16bit mono PCM).
|
||||
* @returns {PushAudioInputStream} The push audio input stream being created.
|
||||
*/
|
||||
public static create(format?: AudioStreamFormat): PushAudioInputStream {
|
||||
|
@ -182,11 +183,11 @@ export class PushAudioInputStreamImpl extends PushAudioInputStream implements IA
|
|||
}
|
||||
|
||||
public get blob(): Promise<Blob | Buffer> {
|
||||
return this.attach("id").then<Blob | Buffer>((audioNode: IAudioStreamNode) => {
|
||||
return this.attach("id").then<Blob | Buffer>((audioNode: IAudioStreamNode): Promise<Blob | Buffer> => {
|
||||
const data: ArrayBuffer[] = [];
|
||||
let bufferData = Buffer.from("");
|
||||
const readCycle = (): Promise<Blob | Buffer> => {
|
||||
return audioNode.read().then<Blob | Buffer>((audioStreamChunk: IStreamChunk<ArrayBuffer>) => {
|
||||
const readCycle = (): Promise<Blob | Buffer> =>
|
||||
audioNode.read().then<Blob | Buffer>((audioStreamChunk: IStreamChunk<ArrayBuffer>): Promise<Blob | Buffer> => {
|
||||
if (!audioStreamChunk || audioStreamChunk.isEnd) {
|
||||
if (typeof (XMLHttpRequest) !== "undefined" && typeof (Blob) !== "undefined") {
|
||||
return Promise.resolve(new Blob(data));
|
||||
|
@ -202,7 +203,6 @@ export class PushAudioInputStreamImpl extends PushAudioInputStream implements IA
|
|||
return readCycle();
|
||||
}
|
||||
});
|
||||
};
|
||||
return readCycle();
|
||||
});
|
||||
}
|
||||
|
@ -220,16 +220,12 @@ export class PushAudioInputStreamImpl extends PushAudioInputStream implements IA
|
|||
const stream = this.privStream;
|
||||
this.onEvent(new AudioStreamNodeAttachedEvent(this.privId, audioNodeId));
|
||||
return {
|
||||
detach: async () => {
|
||||
detach: async (): Promise<void> => {
|
||||
this.onEvent(new AudioStreamNodeDetachedEvent(this.privId, audioNodeId));
|
||||
return this.turnOff();
|
||||
},
|
||||
id: () => {
|
||||
return audioNodeId;
|
||||
},
|
||||
read: () => {
|
||||
return stream.read();
|
||||
},
|
||||
id: (): string => audioNodeId,
|
||||
read: (): Promise<IStreamChunk<ArrayBuffer>> => stream.read(),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -257,7 +253,7 @@ export class PushAudioInputStreamImpl extends PushAudioInputStream implements IA
|
|||
});
|
||||
}
|
||||
|
||||
private onEvent = (event: AudioSourceEvent): void => {
|
||||
private onEvent(event: AudioSourceEvent): void {
|
||||
this.privEvents.onEvent(event);
|
||||
Events.instance.onEvent(event);
|
||||
}
|
||||
|
@ -281,7 +277,9 @@ export abstract class PullAudioInputStream extends AudioInputStream {
|
|||
* Creates and initializes and instance.
|
||||
* @constructor
|
||||
*/
|
||||
protected constructor() { super(); }
|
||||
protected constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a PullAudioInputStream that delegates to the specified callback interface for
|
||||
|
@ -290,9 +288,9 @@ export abstract class PullAudioInputStream extends AudioInputStream {
|
|||
* @function
|
||||
* @public
|
||||
* @param {PullAudioInputStreamCallback} callback - The custom audio input object,
|
||||
* derived from PullAudioInputStreamCustomCallback
|
||||
* derived from PullAudioInputStreamCustomCallback
|
||||
* @param {AudioStreamFormat} format - The audio data format in which audio will be
|
||||
* returned from the callback's read() method (Required if format is not 16 kHz 16bit mono PCM).
|
||||
* returned from the callback's read() method (Required if format is not 16 kHz 16bit mono PCM).
|
||||
* @returns {PullAudioInputStream} The push audio input stream being created.
|
||||
*/
|
||||
public static create(callback: PullAudioInputStreamCallback, format?: AudioStreamFormat): PullAudioInputStream {
|
||||
|
@ -328,9 +326,9 @@ export class PullAudioInputStreamImpl extends PullAudioInputStream implements IA
|
|||
* read() and close() methods, using the default format (16 kHz 16bit mono PCM).
|
||||
* @constructor
|
||||
* @param {PullAudioInputStreamCallback} callback - The custom audio input object,
|
||||
* derived from PullAudioInputStreamCustomCallback
|
||||
* derived from PullAudioInputStreamCustomCallback
|
||||
* @param {AudioStreamFormat} format - The audio data format in which audio will be
|
||||
* returned from the callback's read() method (Required if format is not 16 kHz 16bit mono PCM).
|
||||
* returned from the callback's read() method (Required if format is not 16 kHz 16bit mono PCM).
|
||||
*/
|
||||
public constructor(callback: PullAudioInputStreamCallback, format?: AudioStreamFormatImpl) {
|
||||
super();
|
||||
|
@ -384,14 +382,12 @@ export class PullAudioInputStreamImpl extends PullAudioInputStream implements IA
|
|||
await this.turnOn();
|
||||
this.onEvent(new AudioStreamNodeAttachedEvent(this.privId, audioNodeId));
|
||||
return {
|
||||
detach: () => {
|
||||
detach: (): Promise<void> => {
|
||||
this.privCallback.close();
|
||||
this.onEvent(new AudioStreamNodeDetachedEvent(this.privId, audioNodeId));
|
||||
return this.turnOff();
|
||||
},
|
||||
id: () => {
|
||||
return audioNodeId;
|
||||
},
|
||||
id: (): string => audioNodeId,
|
||||
read: (): Promise<IStreamChunk<ArrayBuffer>> => {
|
||||
let totalBytes: number = 0;
|
||||
let transmitBuff: ArrayBuffer;
|
||||
|
@ -450,7 +446,7 @@ export class PullAudioInputStreamImpl extends PullAudioInputStream implements IA
|
|||
});
|
||||
}
|
||||
|
||||
private onEvent = (event: AudioSourceEvent): void => {
|
||||
private onEvent(event: AudioSourceEvent): void {
|
||||
this.privEvents.onEvent(event);
|
||||
Events.instance.onEvent(event);
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import { AudioFormatTag, AudioStreamFormatImpl } from "./AudioStreamFormat";
|
|||
* @class AudioOutputFormatImpl
|
||||
* Updated in version 1.17.0
|
||||
*/
|
||||
// tslint:disable-next-line:max-classes-per-file
|
||||
// eslint-disable-next-line max-classes-per-file
|
||||
export class AudioOutputFormatImpl extends AudioStreamFormatImpl {
|
||||
public static SpeechSynthesisOutputFormatToString: INumberDictionary<string> = {
|
||||
[SpeechSynthesisOutputFormat.Raw8Khz8BitMonoMULaw]: "raw-8khz-8bit-mono-mulaw",
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// tslint:disable:max-classes-per-file
|
||||
/* eslint-disable max-classes-per-file */
|
||||
|
||||
import {
|
||||
createNoDashGuid,
|
||||
Deferred,
|
||||
IAudioDestination,
|
||||
IStreamChunk,
|
||||
Stream,
|
||||
|
@ -27,7 +26,9 @@ export abstract class AudioOutputStream {
|
|||
* Creates and initializes an instance.
|
||||
* @constructor
|
||||
*/
|
||||
protected constructor() { }
|
||||
protected constructor() {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the format of the AudioOutputStream
|
||||
|
@ -188,7 +189,7 @@ export class PullAudioOutputStreamImpl extends PullAudioOutputStream implements
|
|||
intView.set(new Int8Array(tmpBuffer), totalBytes);
|
||||
totalBytes += tmpBuffer.byteLength;
|
||||
} else {
|
||||
await this.privStream.readEnded();
|
||||
this.privStream.readEnded();
|
||||
}
|
||||
}
|
||||
return totalBytes;
|
||||
|
@ -230,7 +231,9 @@ export abstract class PushAudioOutputStream extends AudioOutputStream {
|
|||
* Creates and initializes and instance.
|
||||
* @constructor
|
||||
*/
|
||||
protected constructor() { super(); }
|
||||
protected constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a PushAudioOutputStream that delegates to the specified callback interface for
|
||||
|
@ -239,7 +242,7 @@ export abstract class PushAudioOutputStream extends AudioOutputStream {
|
|||
* @function
|
||||
* @public
|
||||
* @param {PushAudioOutputStreamCallback} callback - The custom audio output object,
|
||||
* derived from PushAudioOutputStreamCallback
|
||||
* derived from PushAudioOutputStreamCallback
|
||||
* @returns {PushAudioOutputStream} The push audio output stream being created.
|
||||
*/
|
||||
public static create(callback: PushAudioOutputStreamCallback): PushAudioOutputStream {
|
||||
|
@ -270,7 +273,7 @@ export class PushAudioOutputStreamImpl extends PushAudioOutputStream implements
|
|||
* read() and close() methods.
|
||||
* @constructor
|
||||
* @param {PushAudioOutputStreamCallback} callback - The custom audio output object,
|
||||
* derived from PushAudioOutputStreamCallback
|
||||
* derived from PushAudioOutputStreamCallback
|
||||
*/
|
||||
public constructor(callback: PushAudioOutputStreamCallback) {
|
||||
super();
|
||||
|
@ -278,7 +281,7 @@ export class PushAudioOutputStreamImpl extends PushAudioOutputStream implements
|
|||
this.privCallback = callback;
|
||||
}
|
||||
|
||||
// tslint:disable-next-line:no-empty
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
public set format(format: AudioStreamFormat) { }
|
||||
|
||||
public write(buffer: ArrayBuffer): void {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
// eslint-disable-next-line max-classes-per-file
|
||||
export enum AudioFormatTag {
|
||||
PCM = 1,
|
||||
MuLaw,
|
||||
|
@ -39,7 +40,7 @@ export abstract class AudioStreamFormat {
|
|||
* @param {number} samplesPerSecond - Sample rate, in samples per second (Hertz).
|
||||
* @param {number} bitsPerSample - Bits per sample, typically 16.
|
||||
* @param {number} channels - Number of channels in the waveform-audio data. Monaural data
|
||||
* uses one channel and stereo data uses two channels.
|
||||
* uses one channel and stereo data uses two channels.
|
||||
* @param {AudioFormatTag} format - Audio format (PCM, alaw or mulaw).
|
||||
* @returns {AudioStreamFormat} The audio stream format being created.
|
||||
*/
|
||||
|
@ -55,7 +56,7 @@ export abstract class AudioStreamFormat {
|
|||
* @param {number} samplesPerSecond - Sample rate, in samples per second (Hertz).
|
||||
* @param {number} bitsPerSample - Bits per sample, typically 16.
|
||||
* @param {number} channels - Number of channels in the waveform-audio data. Monaural data
|
||||
* uses one channel and stereo data uses two channels.
|
||||
* uses one channel and stereo data uses two channels.
|
||||
* @returns {AudioStreamFormat} The audio stream format being created.
|
||||
*/
|
||||
public static getWaveFormatPCM(samplesPerSecond: number, bitsPerSample: number, channels: number): AudioStreamFormat {
|
||||
|
@ -75,7 +76,6 @@ export abstract class AudioStreamFormat {
|
|||
* @private
|
||||
* @class AudioStreamFormatImpl
|
||||
*/
|
||||
// tslint:disable-next-line:max-classes-per-file
|
||||
export class AudioStreamFormatImpl extends AudioStreamFormat {
|
||||
protected privHeader: ArrayBuffer;
|
||||
|
||||
|
@ -162,6 +162,7 @@ export class AudioStreamFormatImpl extends AudioStreamFormat {
|
|||
* @public
|
||||
* @returns {AudioContext} An audio context instance
|
||||
*/
|
||||
/* eslint-disable */
|
||||
public static getAudioContext(sampleRate?: number): AudioContext {
|
||||
// Workaround for Speech SDK bug in Safari.
|
||||
const AudioContext = (window as any).AudioContext // our preferred impl
|
||||
|
@ -179,6 +180,7 @@ export class AudioStreamFormatImpl extends AudioStreamFormat {
|
|||
throw new Error("Browser does not support Web Audio API (AudioContext is not available).");
|
||||
}
|
||||
}
|
||||
/* eslint-enable */
|
||||
|
||||
/**
|
||||
* Closes the configuration object.
|
||||
|
@ -186,7 +188,9 @@ export class AudioStreamFormatImpl extends AudioStreamFormat {
|
|||
* @function
|
||||
* @public
|
||||
*/
|
||||
public close(): void { return; }
|
||||
public close(): void {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* The format of the audio, valid values: 1 (PCM)
|
||||
|
@ -240,7 +244,7 @@ export class AudioStreamFormatImpl extends AudioStreamFormat {
|
|||
return this.privHeader;
|
||||
}
|
||||
|
||||
protected setString = (view: DataView, offset: number, str: string): void => {
|
||||
protected setString(view: DataView, offset: number, str: string): void {
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
view.setUint8(offset + i, str.charCodeAt(i));
|
||||
}
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
// Licensed under the MIT license.
|
||||
|
||||
import { InvalidOperationError } from "../../common/Error";
|
||||
import { marshalPromiseToCallbacks } from "../../common/Promise";
|
||||
import { AudioStreamFormat, PullAudioInputStreamCallback } from "../Exports";
|
||||
import { AudioStreamFormat } from "../Exports";
|
||||
import { AudioStreamFormatImpl } from "./AudioStreamFormat";
|
||||
|
||||
type AudioDataTypedArray = Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array;
|
||||
|
@ -38,14 +37,21 @@ export class BaseAudioPlayer {
|
|||
* @param newAudioData audio data to be played.
|
||||
*/
|
||||
public playAudioSample(newAudioData: ArrayBuffer, cb?: () => void, err?: (error: string) => void): void {
|
||||
marshalPromiseToCallbacks((async (): Promise<void> => {
|
||||
this.ensureInitializedContext();
|
||||
const audioData = this.formatAudioData(newAudioData);
|
||||
const newSamplesData = new Float32Array(this.samples.length + audioData.length);
|
||||
newSamplesData.set(this.samples, 0);
|
||||
newSamplesData.set(audioData, this.samples.length);
|
||||
this.samples = newSamplesData;
|
||||
})(), cb, err);
|
||||
try {
|
||||
this.ensureInitializedContext();
|
||||
const audioData = this.formatAudioData(newAudioData);
|
||||
const newSamplesData = new Float32Array(this.samples.length + audioData.length);
|
||||
newSamplesData.set(this.samples, 0);
|
||||
newSamplesData.set(audioData, this.samples.length);
|
||||
this.samples = newSamplesData;
|
||||
if (!!cb) {
|
||||
cb();
|
||||
}
|
||||
} catch (e) {
|
||||
if (!!err) {
|
||||
err(e as string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -54,12 +60,13 @@ export class BaseAudioPlayer {
|
|||
public stopAudio(cb?: () => void, err?: (error: string) => void): void {
|
||||
if (this.audioContext !== null) {
|
||||
this.samples = new Float32Array();
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||
clearInterval(this.autoUpdateBufferTimer);
|
||||
this.audioContext.close().then(() => {
|
||||
this.audioContext.close().then((): void => {
|
||||
if (!!cb) {
|
||||
cb();
|
||||
}
|
||||
}, (error: string) => {
|
||||
}, (error: string): void => {
|
||||
if (!!err) {
|
||||
err(error);
|
||||
}
|
||||
|
@ -77,7 +84,7 @@ export class BaseAudioPlayer {
|
|||
if (this.audioContext === null) {
|
||||
this.createAudioContext();
|
||||
const timerPeriod = 200;
|
||||
this.autoUpdateBufferTimer = setInterval(() => {
|
||||
this.autoUpdateBufferTimer = setInterval((): void => {
|
||||
this.updateAudioBuffer();
|
||||
}, timerPeriod);
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ export class SpeakerAudioDestination implements IAudioDestination, IPlayer {
|
|||
public write(buffer: ArrayBuffer, cb?: () => void, err?: (error: string) => void): void {
|
||||
if (this.privAudioBuffer !== undefined) {
|
||||
this.privAudioBuffer.push(buffer);
|
||||
this.updateSourceBuffer().then(() => {
|
||||
this.updateSourceBuffer().then((): void => {
|
||||
if (!!cb) {
|
||||
cb();
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ export class SpeakerAudioDestination implements IAudioDestination, IPlayer {
|
|||
public close(cb?: () => void, err?: (error: string) => void): void {
|
||||
this.privIsClosed = true;
|
||||
if (this.privSourceBuffer !== undefined) {
|
||||
this.handleSourceBufferUpdateEnd().then(() => {
|
||||
this.handleSourceBufferUpdateEnd().then((): void => {
|
||||
if (!!cb) {
|
||||
cb();
|
||||
}
|
||||
|
@ -91,18 +91,18 @@ export class SpeakerAudioDestination implements IAudioDestination, IPlayer {
|
|||
} else if (this.privAudioOutputStream !== undefined && typeof window !== "undefined") {
|
||||
if ((this.privFormat.formatTag === AudioFormatTag.PCM || this.privFormat.formatTag === AudioFormatTag.MuLaw
|
||||
|| this.privFormat.formatTag === AudioFormatTag.ALaw) && this.privFormat.hasHeader === false) {
|
||||
// tslint:disable-next-line:no-console
|
||||
console.warn(`Play back is not supported for raw PCM, mulaw or alaw format without header.`);
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn("Play back is not supported for raw PCM, mulaw or alaw format without header.");
|
||||
if (!!this.onAudioEnd) {
|
||||
this.onAudioEnd(this);
|
||||
}
|
||||
} else {
|
||||
let receivedAudio = new ArrayBuffer(this.privBytesReceived);
|
||||
this.privAudioOutputStream.read(receivedAudio).then((_: number): void => {
|
||||
this.privAudioOutputStream.read(receivedAudio).then((): void => {
|
||||
receivedAudio = SynthesisAdapterBase.addHeader(receivedAudio, this.privFormat);
|
||||
const audioBlob = new Blob([receivedAudio], { type: AudioFormatToMimeType[this.privFormat.formatTag] });
|
||||
this.privAudio.src = window.URL.createObjectURL(audioBlob);
|
||||
this.notifyPlayback().then(() => {
|
||||
this.notifyPlayback().then((): void => {
|
||||
if (!!cb) {
|
||||
cb();
|
||||
}
|
||||
|
@ -125,12 +125,13 @@ export class SpeakerAudioDestination implements IAudioDestination, IPlayer {
|
|||
}
|
||||
}
|
||||
|
||||
set format(format: AudioStreamFormat) {
|
||||
public set format(format: AudioStreamFormat) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
if (typeof (AudioContext) !== "undefined" || (typeof (window) !== "undefined" && typeof ((window as any).webkitAudioContext) !== "undefined")) {
|
||||
this.privFormat = format as AudioOutputFormatImpl;
|
||||
const mimeType: string = AudioFormatToMimeType[this.privFormat.formatTag];
|
||||
if (mimeType === undefined) {
|
||||
// tslint:disable-next-line:no-console
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(
|
||||
`Unknown mimeType for format ${AudioFormatTag[this.privFormat.formatTag]}; playback is not supported.`);
|
||||
|
||||
|
@ -140,21 +141,21 @@ export class SpeakerAudioDestination implements IAudioDestination, IPlayer {
|
|||
this.privMediaSource = new MediaSource();
|
||||
this.privAudio.src = URL.createObjectURL(this.privMediaSource);
|
||||
this.privAudio.load();
|
||||
this.privMediaSource.onsourceopen = (event: Event): void => {
|
||||
this.privMediaSource.onsourceopen = (): void => {
|
||||
this.privMediaSourceOpened = true;
|
||||
this.privMediaSource.duration = MediaDurationPlaceholderSeconds;
|
||||
this.privSourceBuffer = this.privMediaSource.addSourceBuffer(mimeType);
|
||||
this.privSourceBuffer.onupdate = (_: Event) => {
|
||||
this.privSourceBuffer.onupdate = (): void => {
|
||||
this.updateSourceBuffer().catch((reason: string): void => {
|
||||
Events.instance.onEvent(new BackgroundEvent(reason));
|
||||
});
|
||||
};
|
||||
this.privSourceBuffer.onupdateend = (_: Event) => {
|
||||
this.privSourceBuffer.onupdateend = (): void => {
|
||||
this.handleSourceBufferUpdateEnd().catch((reason: string): void => {
|
||||
Events.instance.onEvent(new BackgroundEvent(reason));
|
||||
});
|
||||
};
|
||||
this.privSourceBuffer.onupdatestart = (_: Event) => {
|
||||
this.privSourceBuffer.onupdatestart = (): void => {
|
||||
this.privAppendingToBuffer = false;
|
||||
};
|
||||
};
|
||||
|
@ -163,7 +164,7 @@ export class SpeakerAudioDestination implements IAudioDestination, IPlayer {
|
|||
});
|
||||
|
||||
} else {
|
||||
// tslint:disable-next-line:no-console
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(
|
||||
`Format ${AudioFormatTag[this.privFormat.formatTag]} could not be played by MSE, streaming playback is not enabled.`);
|
||||
this.privAudioOutputStream = new PullAudioOutputStreamImpl();
|
||||
|
@ -215,7 +216,7 @@ export class SpeakerAudioDestination implements IAudioDestination, IPlayer {
|
|||
|
||||
public resume(cb?: () => void, err?: (error: string) => void): void {
|
||||
if (this.privIsPaused && this.privAudio !== undefined) {
|
||||
this.privAudio.play().then(() => {
|
||||
this.privAudio.play().then((): void => {
|
||||
if (!!cb) {
|
||||
cb();
|
||||
}
|
||||
|
@ -244,7 +245,7 @@ export class SpeakerAudioDestination implements IAudioDestination, IPlayer {
|
|||
this.privSourceBuffer.appendBuffer(binary);
|
||||
} catch (error) {
|
||||
this.privAudioBuffer.unshift(binary);
|
||||
// tslint:disable-next-line:no-console
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(
|
||||
"buffer filled, pausing addition of binaries until space is made");
|
||||
return;
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче