antaeus.keycloak.react 2.5.0 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +114 -1
- package/dist/index.d.ts +114 -1
- package/dist/index.js +3045 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3045 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +8 -1
package/dist/index.js
CHANGED
|
@@ -8,7 +8,12 @@ var reactRouterDom = require('react-router-dom');
|
|
|
8
8
|
var qrcode_react = require('qrcode.react');
|
|
9
9
|
|
|
10
10
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
11
|
-
|
|
11
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
12
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
13
|
+
}) : x)(function(x) {
|
|
14
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
15
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
16
|
+
});
|
|
12
17
|
|
|
13
18
|
// src/config/defaults.ts
|
|
14
19
|
var defaultConfig = {
|
|
@@ -1884,6 +1889,3044 @@ function useProtectedFetch(options = {}) {
|
|
|
1884
1889
|
};
|
|
1885
1890
|
}
|
|
1886
1891
|
|
|
1892
|
+
// node_modules/@microsoft/signalr/dist/esm/Errors.js
|
|
1893
|
+
var HttpError = class extends Error {
|
|
1894
|
+
/** Constructs a new instance of {@link @microsoft/signalr.HttpError}.
|
|
1895
|
+
*
|
|
1896
|
+
* @param {string} errorMessage A descriptive error message.
|
|
1897
|
+
* @param {number} statusCode The HTTP status code represented by this error.
|
|
1898
|
+
*/
|
|
1899
|
+
constructor(errorMessage, statusCode) {
|
|
1900
|
+
const trueProto = new.target.prototype;
|
|
1901
|
+
super(`${errorMessage}: Status code '${statusCode}'`);
|
|
1902
|
+
this.statusCode = statusCode;
|
|
1903
|
+
this.__proto__ = trueProto;
|
|
1904
|
+
}
|
|
1905
|
+
};
|
|
1906
|
+
var TimeoutError = class extends Error {
|
|
1907
|
+
/** Constructs a new instance of {@link @microsoft/signalr.TimeoutError}.
|
|
1908
|
+
*
|
|
1909
|
+
* @param {string} errorMessage A descriptive error message.
|
|
1910
|
+
*/
|
|
1911
|
+
constructor(errorMessage = "A timeout occurred.") {
|
|
1912
|
+
const trueProto = new.target.prototype;
|
|
1913
|
+
super(errorMessage);
|
|
1914
|
+
this.__proto__ = trueProto;
|
|
1915
|
+
}
|
|
1916
|
+
};
|
|
1917
|
+
var AbortError = class extends Error {
|
|
1918
|
+
/** Constructs a new instance of {@link AbortError}.
|
|
1919
|
+
*
|
|
1920
|
+
* @param {string} errorMessage A descriptive error message.
|
|
1921
|
+
*/
|
|
1922
|
+
constructor(errorMessage = "An abort occurred.") {
|
|
1923
|
+
const trueProto = new.target.prototype;
|
|
1924
|
+
super(errorMessage);
|
|
1925
|
+
this.__proto__ = trueProto;
|
|
1926
|
+
}
|
|
1927
|
+
};
|
|
1928
|
+
var UnsupportedTransportError = class extends Error {
|
|
1929
|
+
/** Constructs a new instance of {@link @microsoft/signalr.UnsupportedTransportError}.
|
|
1930
|
+
*
|
|
1931
|
+
* @param {string} message A descriptive error message.
|
|
1932
|
+
* @param {HttpTransportType} transport The {@link @microsoft/signalr.HttpTransportType} this error occurred on.
|
|
1933
|
+
*/
|
|
1934
|
+
constructor(message, transport) {
|
|
1935
|
+
const trueProto = new.target.prototype;
|
|
1936
|
+
super(message);
|
|
1937
|
+
this.transport = transport;
|
|
1938
|
+
this.errorType = "UnsupportedTransportError";
|
|
1939
|
+
this.__proto__ = trueProto;
|
|
1940
|
+
}
|
|
1941
|
+
};
|
|
1942
|
+
var DisabledTransportError = class extends Error {
|
|
1943
|
+
/** Constructs a new instance of {@link @microsoft/signalr.DisabledTransportError}.
|
|
1944
|
+
*
|
|
1945
|
+
* @param {string} message A descriptive error message.
|
|
1946
|
+
* @param {HttpTransportType} transport The {@link @microsoft/signalr.HttpTransportType} this error occurred on.
|
|
1947
|
+
*/
|
|
1948
|
+
constructor(message, transport) {
|
|
1949
|
+
const trueProto = new.target.prototype;
|
|
1950
|
+
super(message);
|
|
1951
|
+
this.transport = transport;
|
|
1952
|
+
this.errorType = "DisabledTransportError";
|
|
1953
|
+
this.__proto__ = trueProto;
|
|
1954
|
+
}
|
|
1955
|
+
};
|
|
1956
|
+
var FailedToStartTransportError = class extends Error {
|
|
1957
|
+
/** Constructs a new instance of {@link @microsoft/signalr.FailedToStartTransportError}.
|
|
1958
|
+
*
|
|
1959
|
+
* @param {string} message A descriptive error message.
|
|
1960
|
+
* @param {HttpTransportType} transport The {@link @microsoft/signalr.HttpTransportType} this error occurred on.
|
|
1961
|
+
*/
|
|
1962
|
+
constructor(message, transport) {
|
|
1963
|
+
const trueProto = new.target.prototype;
|
|
1964
|
+
super(message);
|
|
1965
|
+
this.transport = transport;
|
|
1966
|
+
this.errorType = "FailedToStartTransportError";
|
|
1967
|
+
this.__proto__ = trueProto;
|
|
1968
|
+
}
|
|
1969
|
+
};
|
|
1970
|
+
var FailedToNegotiateWithServerError = class extends Error {
|
|
1971
|
+
/** Constructs a new instance of {@link @microsoft/signalr.FailedToNegotiateWithServerError}.
|
|
1972
|
+
*
|
|
1973
|
+
* @param {string} message A descriptive error message.
|
|
1974
|
+
*/
|
|
1975
|
+
constructor(message) {
|
|
1976
|
+
const trueProto = new.target.prototype;
|
|
1977
|
+
super(message);
|
|
1978
|
+
this.errorType = "FailedToNegotiateWithServerError";
|
|
1979
|
+
this.__proto__ = trueProto;
|
|
1980
|
+
}
|
|
1981
|
+
};
|
|
1982
|
+
var AggregateErrors = class extends Error {
|
|
1983
|
+
/** Constructs a new instance of {@link @microsoft/signalr.AggregateErrors}.
|
|
1984
|
+
*
|
|
1985
|
+
* @param {string} message A descriptive error message.
|
|
1986
|
+
* @param {Error[]} innerErrors The collection of errors this error is aggregating.
|
|
1987
|
+
*/
|
|
1988
|
+
constructor(message, innerErrors) {
|
|
1989
|
+
const trueProto = new.target.prototype;
|
|
1990
|
+
super(message);
|
|
1991
|
+
this.innerErrors = innerErrors;
|
|
1992
|
+
this.__proto__ = trueProto;
|
|
1993
|
+
}
|
|
1994
|
+
};
|
|
1995
|
+
|
|
1996
|
+
// node_modules/@microsoft/signalr/dist/esm/HttpClient.js
|
|
1997
|
+
var HttpResponse = class {
|
|
1998
|
+
constructor(statusCode, statusText, content) {
|
|
1999
|
+
this.statusCode = statusCode;
|
|
2000
|
+
this.statusText = statusText;
|
|
2001
|
+
this.content = content;
|
|
2002
|
+
}
|
|
2003
|
+
};
|
|
2004
|
+
var HttpClient = class {
|
|
2005
|
+
get(url, options) {
|
|
2006
|
+
return this.send({
|
|
2007
|
+
...options,
|
|
2008
|
+
method: "GET",
|
|
2009
|
+
url
|
|
2010
|
+
});
|
|
2011
|
+
}
|
|
2012
|
+
post(url, options) {
|
|
2013
|
+
return this.send({
|
|
2014
|
+
...options,
|
|
2015
|
+
method: "POST",
|
|
2016
|
+
url
|
|
2017
|
+
});
|
|
2018
|
+
}
|
|
2019
|
+
delete(url, options) {
|
|
2020
|
+
return this.send({
|
|
2021
|
+
...options,
|
|
2022
|
+
method: "DELETE",
|
|
2023
|
+
url
|
|
2024
|
+
});
|
|
2025
|
+
}
|
|
2026
|
+
/** Gets all cookies that apply to the specified URL.
|
|
2027
|
+
*
|
|
2028
|
+
* @param url The URL that the cookies are valid for.
|
|
2029
|
+
* @returns {string} A string containing all the key-value cookie pairs for the specified URL.
|
|
2030
|
+
*/
|
|
2031
|
+
// @ts-ignore
|
|
2032
|
+
getCookieString(url) {
|
|
2033
|
+
return "";
|
|
2034
|
+
}
|
|
2035
|
+
};
|
|
2036
|
+
|
|
2037
|
+
// node_modules/@microsoft/signalr/dist/esm/ILogger.js
|
|
2038
|
+
var LogLevel;
|
|
2039
|
+
(function(LogLevel2) {
|
|
2040
|
+
LogLevel2[LogLevel2["Trace"] = 0] = "Trace";
|
|
2041
|
+
LogLevel2[LogLevel2["Debug"] = 1] = "Debug";
|
|
2042
|
+
LogLevel2[LogLevel2["Information"] = 2] = "Information";
|
|
2043
|
+
LogLevel2[LogLevel2["Warning"] = 3] = "Warning";
|
|
2044
|
+
LogLevel2[LogLevel2["Error"] = 4] = "Error";
|
|
2045
|
+
LogLevel2[LogLevel2["Critical"] = 5] = "Critical";
|
|
2046
|
+
LogLevel2[LogLevel2["None"] = 6] = "None";
|
|
2047
|
+
})(LogLevel || (LogLevel = {}));
|
|
2048
|
+
|
|
2049
|
+
// node_modules/@microsoft/signalr/dist/esm/Loggers.js
|
|
2050
|
+
var NullLogger = class {
|
|
2051
|
+
constructor() {
|
|
2052
|
+
}
|
|
2053
|
+
/** @inheritDoc */
|
|
2054
|
+
// eslint-disable-next-line
|
|
2055
|
+
log(_logLevel, _message) {
|
|
2056
|
+
}
|
|
2057
|
+
};
|
|
2058
|
+
NullLogger.instance = new NullLogger();
|
|
2059
|
+
|
|
2060
|
+
// node_modules/@microsoft/signalr/dist/esm/Utils.js
|
|
2061
|
+
var VERSION = "8.0.17";
|
|
2062
|
+
var Arg = class {
|
|
2063
|
+
static isRequired(val, name) {
|
|
2064
|
+
if (val === null || val === void 0) {
|
|
2065
|
+
throw new Error(`The '${name}' argument is required.`);
|
|
2066
|
+
}
|
|
2067
|
+
}
|
|
2068
|
+
static isNotEmpty(val, name) {
|
|
2069
|
+
if (!val || val.match(/^\s*$/)) {
|
|
2070
|
+
throw new Error(`The '${name}' argument should not be empty.`);
|
|
2071
|
+
}
|
|
2072
|
+
}
|
|
2073
|
+
static isIn(val, values, name) {
|
|
2074
|
+
if (!(val in values)) {
|
|
2075
|
+
throw new Error(`Unknown ${name} value: ${val}.`);
|
|
2076
|
+
}
|
|
2077
|
+
}
|
|
2078
|
+
};
|
|
2079
|
+
var Platform = class _Platform {
|
|
2080
|
+
// react-native has a window but no document so we should check both
|
|
2081
|
+
static get isBrowser() {
|
|
2082
|
+
return !_Platform.isNode && typeof window === "object" && typeof window.document === "object";
|
|
2083
|
+
}
|
|
2084
|
+
// WebWorkers don't have a window object so the isBrowser check would fail
|
|
2085
|
+
static get isWebWorker() {
|
|
2086
|
+
return !_Platform.isNode && typeof self === "object" && "importScripts" in self;
|
|
2087
|
+
}
|
|
2088
|
+
// react-native has a window but no document
|
|
2089
|
+
static get isReactNative() {
|
|
2090
|
+
return !_Platform.isNode && typeof window === "object" && typeof window.document === "undefined";
|
|
2091
|
+
}
|
|
2092
|
+
// Node apps shouldn't have a window object, but WebWorkers don't either
|
|
2093
|
+
// so we need to check for both WebWorker and window
|
|
2094
|
+
static get isNode() {
|
|
2095
|
+
return typeof process !== "undefined" && process.release && process.release.name === "node";
|
|
2096
|
+
}
|
|
2097
|
+
};
|
|
2098
|
+
function getDataDetail(data, includeContent) {
|
|
2099
|
+
let detail = "";
|
|
2100
|
+
if (isArrayBuffer(data)) {
|
|
2101
|
+
detail = `Binary data of length ${data.byteLength}`;
|
|
2102
|
+
if (includeContent) {
|
|
2103
|
+
detail += `. Content: '${formatArrayBuffer(data)}'`;
|
|
2104
|
+
}
|
|
2105
|
+
} else if (typeof data === "string") {
|
|
2106
|
+
detail = `String data of length ${data.length}`;
|
|
2107
|
+
if (includeContent) {
|
|
2108
|
+
detail += `. Content: '${data}'`;
|
|
2109
|
+
}
|
|
2110
|
+
}
|
|
2111
|
+
return detail;
|
|
2112
|
+
}
|
|
2113
|
+
function formatArrayBuffer(data) {
|
|
2114
|
+
const view = new Uint8Array(data);
|
|
2115
|
+
let str = "";
|
|
2116
|
+
view.forEach((num) => {
|
|
2117
|
+
const pad = num < 16 ? "0" : "";
|
|
2118
|
+
str += `0x${pad}${num.toString(16)} `;
|
|
2119
|
+
});
|
|
2120
|
+
return str.substr(0, str.length - 1);
|
|
2121
|
+
}
|
|
2122
|
+
function isArrayBuffer(val) {
|
|
2123
|
+
return val && typeof ArrayBuffer !== "undefined" && (val instanceof ArrayBuffer || // Sometimes we get an ArrayBuffer that doesn't satisfy instanceof
|
|
2124
|
+
val.constructor && val.constructor.name === "ArrayBuffer");
|
|
2125
|
+
}
|
|
2126
|
+
async function sendMessage(logger, transportName, httpClient, url, content, options) {
|
|
2127
|
+
const headers = {};
|
|
2128
|
+
const [name, value] = getUserAgentHeader();
|
|
2129
|
+
headers[name] = value;
|
|
2130
|
+
logger.log(LogLevel.Trace, `(${transportName} transport) sending data. ${getDataDetail(content, options.logMessageContent)}.`);
|
|
2131
|
+
const responseType = isArrayBuffer(content) ? "arraybuffer" : "text";
|
|
2132
|
+
const response = await httpClient.post(url, {
|
|
2133
|
+
content,
|
|
2134
|
+
headers: { ...headers, ...options.headers },
|
|
2135
|
+
responseType,
|
|
2136
|
+
timeout: options.timeout,
|
|
2137
|
+
withCredentials: options.withCredentials
|
|
2138
|
+
});
|
|
2139
|
+
logger.log(LogLevel.Trace, `(${transportName} transport) request complete. Response status: ${response.statusCode}.`);
|
|
2140
|
+
}
|
|
2141
|
+
function createLogger(logger) {
|
|
2142
|
+
if (logger === void 0) {
|
|
2143
|
+
return new ConsoleLogger(LogLevel.Information);
|
|
2144
|
+
}
|
|
2145
|
+
if (logger === null) {
|
|
2146
|
+
return NullLogger.instance;
|
|
2147
|
+
}
|
|
2148
|
+
if (logger.log !== void 0) {
|
|
2149
|
+
return logger;
|
|
2150
|
+
}
|
|
2151
|
+
return new ConsoleLogger(logger);
|
|
2152
|
+
}
|
|
2153
|
+
var SubjectSubscription = class {
|
|
2154
|
+
constructor(subject, observer) {
|
|
2155
|
+
this._subject = subject;
|
|
2156
|
+
this._observer = observer;
|
|
2157
|
+
}
|
|
2158
|
+
dispose() {
|
|
2159
|
+
const index = this._subject.observers.indexOf(this._observer);
|
|
2160
|
+
if (index > -1) {
|
|
2161
|
+
this._subject.observers.splice(index, 1);
|
|
2162
|
+
}
|
|
2163
|
+
if (this._subject.observers.length === 0 && this._subject.cancelCallback) {
|
|
2164
|
+
this._subject.cancelCallback().catch((_) => {
|
|
2165
|
+
});
|
|
2166
|
+
}
|
|
2167
|
+
}
|
|
2168
|
+
};
|
|
2169
|
+
var ConsoleLogger = class {
|
|
2170
|
+
constructor(minimumLogLevel) {
|
|
2171
|
+
this._minLevel = minimumLogLevel;
|
|
2172
|
+
this.out = console;
|
|
2173
|
+
}
|
|
2174
|
+
log(logLevel, message) {
|
|
2175
|
+
if (logLevel >= this._minLevel) {
|
|
2176
|
+
const msg = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${LogLevel[logLevel]}: ${message}`;
|
|
2177
|
+
switch (logLevel) {
|
|
2178
|
+
case LogLevel.Critical:
|
|
2179
|
+
case LogLevel.Error:
|
|
2180
|
+
this.out.error(msg);
|
|
2181
|
+
break;
|
|
2182
|
+
case LogLevel.Warning:
|
|
2183
|
+
this.out.warn(msg);
|
|
2184
|
+
break;
|
|
2185
|
+
case LogLevel.Information:
|
|
2186
|
+
this.out.info(msg);
|
|
2187
|
+
break;
|
|
2188
|
+
default:
|
|
2189
|
+
this.out.log(msg);
|
|
2190
|
+
break;
|
|
2191
|
+
}
|
|
2192
|
+
}
|
|
2193
|
+
}
|
|
2194
|
+
};
|
|
2195
|
+
function getUserAgentHeader() {
|
|
2196
|
+
let userAgentHeaderName = "X-SignalR-User-Agent";
|
|
2197
|
+
if (Platform.isNode) {
|
|
2198
|
+
userAgentHeaderName = "User-Agent";
|
|
2199
|
+
}
|
|
2200
|
+
return [userAgentHeaderName, constructUserAgent(VERSION, getOsName(), getRuntime(), getRuntimeVersion())];
|
|
2201
|
+
}
|
|
2202
|
+
function constructUserAgent(version, os, runtime, runtimeVersion) {
|
|
2203
|
+
let userAgent = "Microsoft SignalR/";
|
|
2204
|
+
const majorAndMinor = version.split(".");
|
|
2205
|
+
userAgent += `${majorAndMinor[0]}.${majorAndMinor[1]}`;
|
|
2206
|
+
userAgent += ` (${version}; `;
|
|
2207
|
+
if (os && os !== "") {
|
|
2208
|
+
userAgent += `${os}; `;
|
|
2209
|
+
} else {
|
|
2210
|
+
userAgent += "Unknown OS; ";
|
|
2211
|
+
}
|
|
2212
|
+
userAgent += `${runtime}`;
|
|
2213
|
+
if (runtimeVersion) {
|
|
2214
|
+
userAgent += `; ${runtimeVersion}`;
|
|
2215
|
+
} else {
|
|
2216
|
+
userAgent += "; Unknown Runtime Version";
|
|
2217
|
+
}
|
|
2218
|
+
userAgent += ")";
|
|
2219
|
+
return userAgent;
|
|
2220
|
+
}
|
|
2221
|
+
function getOsName() {
|
|
2222
|
+
if (Platform.isNode) {
|
|
2223
|
+
switch (process.platform) {
|
|
2224
|
+
case "win32":
|
|
2225
|
+
return "Windows NT";
|
|
2226
|
+
case "darwin":
|
|
2227
|
+
return "macOS";
|
|
2228
|
+
case "linux":
|
|
2229
|
+
return "Linux";
|
|
2230
|
+
default:
|
|
2231
|
+
return process.platform;
|
|
2232
|
+
}
|
|
2233
|
+
} else {
|
|
2234
|
+
return "";
|
|
2235
|
+
}
|
|
2236
|
+
}
|
|
2237
|
+
function getRuntimeVersion() {
|
|
2238
|
+
if (Platform.isNode) {
|
|
2239
|
+
return process.versions.node;
|
|
2240
|
+
}
|
|
2241
|
+
return void 0;
|
|
2242
|
+
}
|
|
2243
|
+
function getRuntime() {
|
|
2244
|
+
if (Platform.isNode) {
|
|
2245
|
+
return "NodeJS";
|
|
2246
|
+
} else {
|
|
2247
|
+
return "Browser";
|
|
2248
|
+
}
|
|
2249
|
+
}
|
|
2250
|
+
function getErrorString(e) {
|
|
2251
|
+
if (e.stack) {
|
|
2252
|
+
return e.stack;
|
|
2253
|
+
} else if (e.message) {
|
|
2254
|
+
return e.message;
|
|
2255
|
+
}
|
|
2256
|
+
return `${e}`;
|
|
2257
|
+
}
|
|
2258
|
+
function getGlobalThis() {
|
|
2259
|
+
if (typeof globalThis !== "undefined") {
|
|
2260
|
+
return globalThis;
|
|
2261
|
+
}
|
|
2262
|
+
if (typeof self !== "undefined") {
|
|
2263
|
+
return self;
|
|
2264
|
+
}
|
|
2265
|
+
if (typeof window !== "undefined") {
|
|
2266
|
+
return window;
|
|
2267
|
+
}
|
|
2268
|
+
if (typeof global !== "undefined") {
|
|
2269
|
+
return global;
|
|
2270
|
+
}
|
|
2271
|
+
throw new Error("could not find global");
|
|
2272
|
+
}
|
|
2273
|
+
|
|
2274
|
+
// node_modules/@microsoft/signalr/dist/esm/FetchHttpClient.js
|
|
2275
|
+
var FetchHttpClient = class extends HttpClient {
|
|
2276
|
+
constructor(logger) {
|
|
2277
|
+
super();
|
|
2278
|
+
this._logger = logger;
|
|
2279
|
+
if (typeof fetch === "undefined" || Platform.isNode) {
|
|
2280
|
+
const requireFunc = typeof __webpack_require__ === "function" ? __non_webpack_require__ : __require;
|
|
2281
|
+
this._jar = new (requireFunc("tough-cookie")).CookieJar();
|
|
2282
|
+
if (typeof fetch === "undefined") {
|
|
2283
|
+
this._fetchType = requireFunc("node-fetch");
|
|
2284
|
+
} else {
|
|
2285
|
+
this._fetchType = fetch;
|
|
2286
|
+
}
|
|
2287
|
+
this._fetchType = requireFunc("fetch-cookie")(this._fetchType, this._jar);
|
|
2288
|
+
} else {
|
|
2289
|
+
this._fetchType = fetch.bind(getGlobalThis());
|
|
2290
|
+
}
|
|
2291
|
+
if (typeof AbortController === "undefined") {
|
|
2292
|
+
const requireFunc = typeof __webpack_require__ === "function" ? __non_webpack_require__ : __require;
|
|
2293
|
+
this._abortControllerType = requireFunc("abort-controller");
|
|
2294
|
+
} else {
|
|
2295
|
+
this._abortControllerType = AbortController;
|
|
2296
|
+
}
|
|
2297
|
+
}
|
|
2298
|
+
/** @inheritDoc */
|
|
2299
|
+
async send(request) {
|
|
2300
|
+
if (request.abortSignal && request.abortSignal.aborted) {
|
|
2301
|
+
throw new AbortError();
|
|
2302
|
+
}
|
|
2303
|
+
if (!request.method) {
|
|
2304
|
+
throw new Error("No method defined.");
|
|
2305
|
+
}
|
|
2306
|
+
if (!request.url) {
|
|
2307
|
+
throw new Error("No url defined.");
|
|
2308
|
+
}
|
|
2309
|
+
const abortController = new this._abortControllerType();
|
|
2310
|
+
let error;
|
|
2311
|
+
if (request.abortSignal) {
|
|
2312
|
+
request.abortSignal.onabort = () => {
|
|
2313
|
+
abortController.abort();
|
|
2314
|
+
error = new AbortError();
|
|
2315
|
+
};
|
|
2316
|
+
}
|
|
2317
|
+
let timeoutId = null;
|
|
2318
|
+
if (request.timeout) {
|
|
2319
|
+
const msTimeout = request.timeout;
|
|
2320
|
+
timeoutId = setTimeout(() => {
|
|
2321
|
+
abortController.abort();
|
|
2322
|
+
this._logger.log(LogLevel.Warning, `Timeout from HTTP request.`);
|
|
2323
|
+
error = new TimeoutError();
|
|
2324
|
+
}, msTimeout);
|
|
2325
|
+
}
|
|
2326
|
+
if (request.content === "") {
|
|
2327
|
+
request.content = void 0;
|
|
2328
|
+
}
|
|
2329
|
+
if (request.content) {
|
|
2330
|
+
request.headers = request.headers || {};
|
|
2331
|
+
if (isArrayBuffer(request.content)) {
|
|
2332
|
+
request.headers["Content-Type"] = "application/octet-stream";
|
|
2333
|
+
} else {
|
|
2334
|
+
request.headers["Content-Type"] = "text/plain;charset=UTF-8";
|
|
2335
|
+
}
|
|
2336
|
+
}
|
|
2337
|
+
let response;
|
|
2338
|
+
try {
|
|
2339
|
+
response = await this._fetchType(request.url, {
|
|
2340
|
+
body: request.content,
|
|
2341
|
+
cache: "no-cache",
|
|
2342
|
+
credentials: request.withCredentials === true ? "include" : "same-origin",
|
|
2343
|
+
headers: {
|
|
2344
|
+
"X-Requested-With": "XMLHttpRequest",
|
|
2345
|
+
...request.headers
|
|
2346
|
+
},
|
|
2347
|
+
method: request.method,
|
|
2348
|
+
mode: "cors",
|
|
2349
|
+
redirect: "follow",
|
|
2350
|
+
signal: abortController.signal
|
|
2351
|
+
});
|
|
2352
|
+
} catch (e) {
|
|
2353
|
+
if (error) {
|
|
2354
|
+
throw error;
|
|
2355
|
+
}
|
|
2356
|
+
this._logger.log(LogLevel.Warning, `Error from HTTP request. ${e}.`);
|
|
2357
|
+
throw e;
|
|
2358
|
+
} finally {
|
|
2359
|
+
if (timeoutId) {
|
|
2360
|
+
clearTimeout(timeoutId);
|
|
2361
|
+
}
|
|
2362
|
+
if (request.abortSignal) {
|
|
2363
|
+
request.abortSignal.onabort = null;
|
|
2364
|
+
}
|
|
2365
|
+
}
|
|
2366
|
+
if (!response.ok) {
|
|
2367
|
+
const errorMessage = await deserializeContent(response, "text");
|
|
2368
|
+
throw new HttpError(errorMessage || response.statusText, response.status);
|
|
2369
|
+
}
|
|
2370
|
+
const content = deserializeContent(response, request.responseType);
|
|
2371
|
+
const payload = await content;
|
|
2372
|
+
return new HttpResponse(response.status, response.statusText, payload);
|
|
2373
|
+
}
|
|
2374
|
+
getCookieString(url) {
|
|
2375
|
+
let cookies = "";
|
|
2376
|
+
if (Platform.isNode && this._jar) {
|
|
2377
|
+
this._jar.getCookies(url, (e, c) => cookies = c.join("; "));
|
|
2378
|
+
}
|
|
2379
|
+
return cookies;
|
|
2380
|
+
}
|
|
2381
|
+
};
|
|
2382
|
+
function deserializeContent(response, responseType) {
|
|
2383
|
+
let content;
|
|
2384
|
+
switch (responseType) {
|
|
2385
|
+
case "arraybuffer":
|
|
2386
|
+
content = response.arrayBuffer();
|
|
2387
|
+
break;
|
|
2388
|
+
case "text":
|
|
2389
|
+
content = response.text();
|
|
2390
|
+
break;
|
|
2391
|
+
case "blob":
|
|
2392
|
+
case "document":
|
|
2393
|
+
case "json":
|
|
2394
|
+
throw new Error(`${responseType} is not supported.`);
|
|
2395
|
+
default:
|
|
2396
|
+
content = response.text();
|
|
2397
|
+
break;
|
|
2398
|
+
}
|
|
2399
|
+
return content;
|
|
2400
|
+
}
|
|
2401
|
+
|
|
2402
|
+
// node_modules/@microsoft/signalr/dist/esm/XhrHttpClient.js
|
|
2403
|
+
var XhrHttpClient = class extends HttpClient {
|
|
2404
|
+
constructor(logger) {
|
|
2405
|
+
super();
|
|
2406
|
+
this._logger = logger;
|
|
2407
|
+
}
|
|
2408
|
+
/** @inheritDoc */
|
|
2409
|
+
send(request) {
|
|
2410
|
+
if (request.abortSignal && request.abortSignal.aborted) {
|
|
2411
|
+
return Promise.reject(new AbortError());
|
|
2412
|
+
}
|
|
2413
|
+
if (!request.method) {
|
|
2414
|
+
return Promise.reject(new Error("No method defined."));
|
|
2415
|
+
}
|
|
2416
|
+
if (!request.url) {
|
|
2417
|
+
return Promise.reject(new Error("No url defined."));
|
|
2418
|
+
}
|
|
2419
|
+
return new Promise((resolve, reject) => {
|
|
2420
|
+
const xhr = new XMLHttpRequest();
|
|
2421
|
+
xhr.open(request.method, request.url, true);
|
|
2422
|
+
xhr.withCredentials = request.withCredentials === void 0 ? true : request.withCredentials;
|
|
2423
|
+
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
|
|
2424
|
+
if (request.content === "") {
|
|
2425
|
+
request.content = void 0;
|
|
2426
|
+
}
|
|
2427
|
+
if (request.content) {
|
|
2428
|
+
if (isArrayBuffer(request.content)) {
|
|
2429
|
+
xhr.setRequestHeader("Content-Type", "application/octet-stream");
|
|
2430
|
+
} else {
|
|
2431
|
+
xhr.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
|
|
2432
|
+
}
|
|
2433
|
+
}
|
|
2434
|
+
const headers = request.headers;
|
|
2435
|
+
if (headers) {
|
|
2436
|
+
Object.keys(headers).forEach((header) => {
|
|
2437
|
+
xhr.setRequestHeader(header, headers[header]);
|
|
2438
|
+
});
|
|
2439
|
+
}
|
|
2440
|
+
if (request.responseType) {
|
|
2441
|
+
xhr.responseType = request.responseType;
|
|
2442
|
+
}
|
|
2443
|
+
if (request.abortSignal) {
|
|
2444
|
+
request.abortSignal.onabort = () => {
|
|
2445
|
+
xhr.abort();
|
|
2446
|
+
reject(new AbortError());
|
|
2447
|
+
};
|
|
2448
|
+
}
|
|
2449
|
+
if (request.timeout) {
|
|
2450
|
+
xhr.timeout = request.timeout;
|
|
2451
|
+
}
|
|
2452
|
+
xhr.onload = () => {
|
|
2453
|
+
if (request.abortSignal) {
|
|
2454
|
+
request.abortSignal.onabort = null;
|
|
2455
|
+
}
|
|
2456
|
+
if (xhr.status >= 200 && xhr.status < 300) {
|
|
2457
|
+
resolve(new HttpResponse(xhr.status, xhr.statusText, xhr.response || xhr.responseText));
|
|
2458
|
+
} else {
|
|
2459
|
+
reject(new HttpError(xhr.response || xhr.responseText || xhr.statusText, xhr.status));
|
|
2460
|
+
}
|
|
2461
|
+
};
|
|
2462
|
+
xhr.onerror = () => {
|
|
2463
|
+
this._logger.log(LogLevel.Warning, `Error from HTTP request. ${xhr.status}: ${xhr.statusText}.`);
|
|
2464
|
+
reject(new HttpError(xhr.statusText, xhr.status));
|
|
2465
|
+
};
|
|
2466
|
+
xhr.ontimeout = () => {
|
|
2467
|
+
this._logger.log(LogLevel.Warning, `Timeout from HTTP request.`);
|
|
2468
|
+
reject(new TimeoutError());
|
|
2469
|
+
};
|
|
2470
|
+
xhr.send(request.content);
|
|
2471
|
+
});
|
|
2472
|
+
}
|
|
2473
|
+
};
|
|
2474
|
+
|
|
2475
|
+
// node_modules/@microsoft/signalr/dist/esm/DefaultHttpClient.js
|
|
2476
|
+
var DefaultHttpClient = class extends HttpClient {
|
|
2477
|
+
/** Creates a new instance of the {@link @microsoft/signalr.DefaultHttpClient}, using the provided {@link @microsoft/signalr.ILogger} to log messages. */
|
|
2478
|
+
constructor(logger) {
|
|
2479
|
+
super();
|
|
2480
|
+
if (typeof fetch !== "undefined" || Platform.isNode) {
|
|
2481
|
+
this._httpClient = new FetchHttpClient(logger);
|
|
2482
|
+
} else if (typeof XMLHttpRequest !== "undefined") {
|
|
2483
|
+
this._httpClient = new XhrHttpClient(logger);
|
|
2484
|
+
} else {
|
|
2485
|
+
throw new Error("No usable HttpClient found.");
|
|
2486
|
+
}
|
|
2487
|
+
}
|
|
2488
|
+
/** @inheritDoc */
|
|
2489
|
+
send(request) {
|
|
2490
|
+
if (request.abortSignal && request.abortSignal.aborted) {
|
|
2491
|
+
return Promise.reject(new AbortError());
|
|
2492
|
+
}
|
|
2493
|
+
if (!request.method) {
|
|
2494
|
+
return Promise.reject(new Error("No method defined."));
|
|
2495
|
+
}
|
|
2496
|
+
if (!request.url) {
|
|
2497
|
+
return Promise.reject(new Error("No url defined."));
|
|
2498
|
+
}
|
|
2499
|
+
return this._httpClient.send(request);
|
|
2500
|
+
}
|
|
2501
|
+
getCookieString(url) {
|
|
2502
|
+
return this._httpClient.getCookieString(url);
|
|
2503
|
+
}
|
|
2504
|
+
};
|
|
2505
|
+
|
|
2506
|
+
// node_modules/@microsoft/signalr/dist/esm/TextMessageFormat.js
|
|
2507
|
+
var TextMessageFormat = class _TextMessageFormat {
|
|
2508
|
+
static write(output) {
|
|
2509
|
+
return `${output}${_TextMessageFormat.RecordSeparator}`;
|
|
2510
|
+
}
|
|
2511
|
+
static parse(input) {
|
|
2512
|
+
if (input[input.length - 1] !== _TextMessageFormat.RecordSeparator) {
|
|
2513
|
+
throw new Error("Message is incomplete.");
|
|
2514
|
+
}
|
|
2515
|
+
const messages = input.split(_TextMessageFormat.RecordSeparator);
|
|
2516
|
+
messages.pop();
|
|
2517
|
+
return messages;
|
|
2518
|
+
}
|
|
2519
|
+
};
|
|
2520
|
+
TextMessageFormat.RecordSeparatorCode = 30;
|
|
2521
|
+
TextMessageFormat.RecordSeparator = String.fromCharCode(TextMessageFormat.RecordSeparatorCode);
|
|
2522
|
+
|
|
2523
|
+
// node_modules/@microsoft/signalr/dist/esm/HandshakeProtocol.js
|
|
2524
|
+
var HandshakeProtocol = class {
|
|
2525
|
+
// Handshake request is always JSON
|
|
2526
|
+
writeHandshakeRequest(handshakeRequest) {
|
|
2527
|
+
return TextMessageFormat.write(JSON.stringify(handshakeRequest));
|
|
2528
|
+
}
|
|
2529
|
+
parseHandshakeResponse(data) {
|
|
2530
|
+
let messageData;
|
|
2531
|
+
let remainingData;
|
|
2532
|
+
if (isArrayBuffer(data)) {
|
|
2533
|
+
const binaryData = new Uint8Array(data);
|
|
2534
|
+
const separatorIndex = binaryData.indexOf(TextMessageFormat.RecordSeparatorCode);
|
|
2535
|
+
if (separatorIndex === -1) {
|
|
2536
|
+
throw new Error("Message is incomplete.");
|
|
2537
|
+
}
|
|
2538
|
+
const responseLength = separatorIndex + 1;
|
|
2539
|
+
messageData = String.fromCharCode.apply(null, Array.prototype.slice.call(binaryData.slice(0, responseLength)));
|
|
2540
|
+
remainingData = binaryData.byteLength > responseLength ? binaryData.slice(responseLength).buffer : null;
|
|
2541
|
+
} else {
|
|
2542
|
+
const textData = data;
|
|
2543
|
+
const separatorIndex = textData.indexOf(TextMessageFormat.RecordSeparator);
|
|
2544
|
+
if (separatorIndex === -1) {
|
|
2545
|
+
throw new Error("Message is incomplete.");
|
|
2546
|
+
}
|
|
2547
|
+
const responseLength = separatorIndex + 1;
|
|
2548
|
+
messageData = textData.substring(0, responseLength);
|
|
2549
|
+
remainingData = textData.length > responseLength ? textData.substring(responseLength) : null;
|
|
2550
|
+
}
|
|
2551
|
+
const messages = TextMessageFormat.parse(messageData);
|
|
2552
|
+
const response = JSON.parse(messages[0]);
|
|
2553
|
+
if (response.type) {
|
|
2554
|
+
throw new Error("Expected a handshake response from the server.");
|
|
2555
|
+
}
|
|
2556
|
+
const responseMessage = response;
|
|
2557
|
+
return [remainingData, responseMessage];
|
|
2558
|
+
}
|
|
2559
|
+
};
|
|
2560
|
+
|
|
2561
|
+
// node_modules/@microsoft/signalr/dist/esm/IHubProtocol.js
|
|
2562
|
+
var MessageType;
|
|
2563
|
+
(function(MessageType2) {
|
|
2564
|
+
MessageType2[MessageType2["Invocation"] = 1] = "Invocation";
|
|
2565
|
+
MessageType2[MessageType2["StreamItem"] = 2] = "StreamItem";
|
|
2566
|
+
MessageType2[MessageType2["Completion"] = 3] = "Completion";
|
|
2567
|
+
MessageType2[MessageType2["StreamInvocation"] = 4] = "StreamInvocation";
|
|
2568
|
+
MessageType2[MessageType2["CancelInvocation"] = 5] = "CancelInvocation";
|
|
2569
|
+
MessageType2[MessageType2["Ping"] = 6] = "Ping";
|
|
2570
|
+
MessageType2[MessageType2["Close"] = 7] = "Close";
|
|
2571
|
+
MessageType2[MessageType2["Ack"] = 8] = "Ack";
|
|
2572
|
+
MessageType2[MessageType2["Sequence"] = 9] = "Sequence";
|
|
2573
|
+
})(MessageType || (MessageType = {}));
|
|
2574
|
+
|
|
2575
|
+
// node_modules/@microsoft/signalr/dist/esm/Subject.js
|
|
2576
|
+
var Subject = class {
|
|
2577
|
+
constructor() {
|
|
2578
|
+
this.observers = [];
|
|
2579
|
+
}
|
|
2580
|
+
next(item) {
|
|
2581
|
+
for (const observer of this.observers) {
|
|
2582
|
+
observer.next(item);
|
|
2583
|
+
}
|
|
2584
|
+
}
|
|
2585
|
+
error(err) {
|
|
2586
|
+
for (const observer of this.observers) {
|
|
2587
|
+
if (observer.error) {
|
|
2588
|
+
observer.error(err);
|
|
2589
|
+
}
|
|
2590
|
+
}
|
|
2591
|
+
}
|
|
2592
|
+
complete() {
|
|
2593
|
+
for (const observer of this.observers) {
|
|
2594
|
+
if (observer.complete) {
|
|
2595
|
+
observer.complete();
|
|
2596
|
+
}
|
|
2597
|
+
}
|
|
2598
|
+
}
|
|
2599
|
+
subscribe(observer) {
|
|
2600
|
+
this.observers.push(observer);
|
|
2601
|
+
return new SubjectSubscription(this, observer);
|
|
2602
|
+
}
|
|
2603
|
+
};
|
|
2604
|
+
|
|
2605
|
+
// node_modules/@microsoft/signalr/dist/esm/MessageBuffer.js
|
|
2606
|
+
var MessageBuffer = class {
|
|
2607
|
+
constructor(protocol, connection, bufferSize) {
|
|
2608
|
+
this._bufferSize = 1e5;
|
|
2609
|
+
this._messages = [];
|
|
2610
|
+
this._totalMessageCount = 0;
|
|
2611
|
+
this._waitForSequenceMessage = false;
|
|
2612
|
+
this._nextReceivingSequenceId = 1;
|
|
2613
|
+
this._latestReceivedSequenceId = 0;
|
|
2614
|
+
this._bufferedByteCount = 0;
|
|
2615
|
+
this._reconnectInProgress = false;
|
|
2616
|
+
this._protocol = protocol;
|
|
2617
|
+
this._connection = connection;
|
|
2618
|
+
this._bufferSize = bufferSize;
|
|
2619
|
+
}
|
|
2620
|
+
async _send(message) {
|
|
2621
|
+
const serializedMessage = this._protocol.writeMessage(message);
|
|
2622
|
+
let backpressurePromise = Promise.resolve();
|
|
2623
|
+
if (this._isInvocationMessage(message)) {
|
|
2624
|
+
this._totalMessageCount++;
|
|
2625
|
+
let backpressurePromiseResolver = () => {
|
|
2626
|
+
};
|
|
2627
|
+
let backpressurePromiseRejector = () => {
|
|
2628
|
+
};
|
|
2629
|
+
if (isArrayBuffer(serializedMessage)) {
|
|
2630
|
+
this._bufferedByteCount += serializedMessage.byteLength;
|
|
2631
|
+
} else {
|
|
2632
|
+
this._bufferedByteCount += serializedMessage.length;
|
|
2633
|
+
}
|
|
2634
|
+
if (this._bufferedByteCount >= this._bufferSize) {
|
|
2635
|
+
backpressurePromise = new Promise((resolve, reject) => {
|
|
2636
|
+
backpressurePromiseResolver = resolve;
|
|
2637
|
+
backpressurePromiseRejector = reject;
|
|
2638
|
+
});
|
|
2639
|
+
}
|
|
2640
|
+
this._messages.push(new BufferedItem(serializedMessage, this._totalMessageCount, backpressurePromiseResolver, backpressurePromiseRejector));
|
|
2641
|
+
}
|
|
2642
|
+
try {
|
|
2643
|
+
if (!this._reconnectInProgress) {
|
|
2644
|
+
await this._connection.send(serializedMessage);
|
|
2645
|
+
}
|
|
2646
|
+
} catch {
|
|
2647
|
+
this._disconnected();
|
|
2648
|
+
}
|
|
2649
|
+
await backpressurePromise;
|
|
2650
|
+
}
|
|
2651
|
+
_ack(ackMessage) {
|
|
2652
|
+
let newestAckedMessage = -1;
|
|
2653
|
+
for (let index = 0; index < this._messages.length; index++) {
|
|
2654
|
+
const element = this._messages[index];
|
|
2655
|
+
if (element._id <= ackMessage.sequenceId) {
|
|
2656
|
+
newestAckedMessage = index;
|
|
2657
|
+
if (isArrayBuffer(element._message)) {
|
|
2658
|
+
this._bufferedByteCount -= element._message.byteLength;
|
|
2659
|
+
} else {
|
|
2660
|
+
this._bufferedByteCount -= element._message.length;
|
|
2661
|
+
}
|
|
2662
|
+
element._resolver();
|
|
2663
|
+
} else if (this._bufferedByteCount < this._bufferSize) {
|
|
2664
|
+
element._resolver();
|
|
2665
|
+
} else {
|
|
2666
|
+
break;
|
|
2667
|
+
}
|
|
2668
|
+
}
|
|
2669
|
+
if (newestAckedMessage !== -1) {
|
|
2670
|
+
this._messages = this._messages.slice(newestAckedMessage + 1);
|
|
2671
|
+
}
|
|
2672
|
+
}
|
|
2673
|
+
_shouldProcessMessage(message) {
|
|
2674
|
+
if (this._waitForSequenceMessage) {
|
|
2675
|
+
if (message.type !== MessageType.Sequence) {
|
|
2676
|
+
return false;
|
|
2677
|
+
} else {
|
|
2678
|
+
this._waitForSequenceMessage = false;
|
|
2679
|
+
return true;
|
|
2680
|
+
}
|
|
2681
|
+
}
|
|
2682
|
+
if (!this._isInvocationMessage(message)) {
|
|
2683
|
+
return true;
|
|
2684
|
+
}
|
|
2685
|
+
const currentId = this._nextReceivingSequenceId;
|
|
2686
|
+
this._nextReceivingSequenceId++;
|
|
2687
|
+
if (currentId <= this._latestReceivedSequenceId) {
|
|
2688
|
+
if (currentId === this._latestReceivedSequenceId) {
|
|
2689
|
+
this._ackTimer();
|
|
2690
|
+
}
|
|
2691
|
+
return false;
|
|
2692
|
+
}
|
|
2693
|
+
this._latestReceivedSequenceId = currentId;
|
|
2694
|
+
this._ackTimer();
|
|
2695
|
+
return true;
|
|
2696
|
+
}
|
|
2697
|
+
_resetSequence(message) {
|
|
2698
|
+
if (message.sequenceId > this._nextReceivingSequenceId) {
|
|
2699
|
+
this._connection.stop(new Error("Sequence ID greater than amount of messages we've received."));
|
|
2700
|
+
return;
|
|
2701
|
+
}
|
|
2702
|
+
this._nextReceivingSequenceId = message.sequenceId;
|
|
2703
|
+
}
|
|
2704
|
+
_disconnected() {
|
|
2705
|
+
this._reconnectInProgress = true;
|
|
2706
|
+
this._waitForSequenceMessage = true;
|
|
2707
|
+
}
|
|
2708
|
+
async _resend() {
|
|
2709
|
+
const sequenceId = this._messages.length !== 0 ? this._messages[0]._id : this._totalMessageCount + 1;
|
|
2710
|
+
await this._connection.send(this._protocol.writeMessage({ type: MessageType.Sequence, sequenceId }));
|
|
2711
|
+
const messages = this._messages;
|
|
2712
|
+
for (const element of messages) {
|
|
2713
|
+
await this._connection.send(element._message);
|
|
2714
|
+
}
|
|
2715
|
+
this._reconnectInProgress = false;
|
|
2716
|
+
}
|
|
2717
|
+
_dispose(error) {
|
|
2718
|
+
error !== null && error !== void 0 ? error : error = new Error("Unable to reconnect to server.");
|
|
2719
|
+
for (const element of this._messages) {
|
|
2720
|
+
element._rejector(error);
|
|
2721
|
+
}
|
|
2722
|
+
}
|
|
2723
|
+
_isInvocationMessage(message) {
|
|
2724
|
+
switch (message.type) {
|
|
2725
|
+
case MessageType.Invocation:
|
|
2726
|
+
case MessageType.StreamItem:
|
|
2727
|
+
case MessageType.Completion:
|
|
2728
|
+
case MessageType.StreamInvocation:
|
|
2729
|
+
case MessageType.CancelInvocation:
|
|
2730
|
+
return true;
|
|
2731
|
+
case MessageType.Close:
|
|
2732
|
+
case MessageType.Sequence:
|
|
2733
|
+
case MessageType.Ping:
|
|
2734
|
+
case MessageType.Ack:
|
|
2735
|
+
return false;
|
|
2736
|
+
}
|
|
2737
|
+
}
|
|
2738
|
+
_ackTimer() {
|
|
2739
|
+
if (this._ackTimerHandle === void 0) {
|
|
2740
|
+
this._ackTimerHandle = setTimeout(async () => {
|
|
2741
|
+
try {
|
|
2742
|
+
if (!this._reconnectInProgress) {
|
|
2743
|
+
await this._connection.send(this._protocol.writeMessage({ type: MessageType.Ack, sequenceId: this._latestReceivedSequenceId }));
|
|
2744
|
+
}
|
|
2745
|
+
} catch {
|
|
2746
|
+
}
|
|
2747
|
+
clearTimeout(this._ackTimerHandle);
|
|
2748
|
+
this._ackTimerHandle = void 0;
|
|
2749
|
+
}, 1e3);
|
|
2750
|
+
}
|
|
2751
|
+
}
|
|
2752
|
+
};
|
|
2753
|
+
var BufferedItem = class {
|
|
2754
|
+
constructor(message, id, resolver, rejector) {
|
|
2755
|
+
this._message = message;
|
|
2756
|
+
this._id = id;
|
|
2757
|
+
this._resolver = resolver;
|
|
2758
|
+
this._rejector = rejector;
|
|
2759
|
+
}
|
|
2760
|
+
};
|
|
2761
|
+
|
|
2762
|
+
// node_modules/@microsoft/signalr/dist/esm/HubConnection.js
|
|
2763
|
+
var DEFAULT_TIMEOUT_IN_MS = 30 * 1e3;
|
|
2764
|
+
var DEFAULT_PING_INTERVAL_IN_MS = 15 * 1e3;
|
|
2765
|
+
var DEFAULT_STATEFUL_RECONNECT_BUFFER_SIZE = 1e5;
|
|
2766
|
+
var HubConnectionState;
|
|
2767
|
+
(function(HubConnectionState2) {
|
|
2768
|
+
HubConnectionState2["Disconnected"] = "Disconnected";
|
|
2769
|
+
HubConnectionState2["Connecting"] = "Connecting";
|
|
2770
|
+
HubConnectionState2["Connected"] = "Connected";
|
|
2771
|
+
HubConnectionState2["Disconnecting"] = "Disconnecting";
|
|
2772
|
+
HubConnectionState2["Reconnecting"] = "Reconnecting";
|
|
2773
|
+
})(HubConnectionState || (HubConnectionState = {}));
|
|
2774
|
+
var HubConnection = class _HubConnection {
|
|
2775
|
+
/** @internal */
|
|
2776
|
+
// Using a public static factory method means we can have a private constructor and an _internal_
|
|
2777
|
+
// create method that can be used by HubConnectionBuilder. An "internal" constructor would just
|
|
2778
|
+
// be stripped away and the '.d.ts' file would have no constructor, which is interpreted as a
|
|
2779
|
+
// public parameter-less constructor.
|
|
2780
|
+
static create(connection, logger, protocol, reconnectPolicy, serverTimeoutInMilliseconds, keepAliveIntervalInMilliseconds, statefulReconnectBufferSize) {
|
|
2781
|
+
return new _HubConnection(connection, logger, protocol, reconnectPolicy, serverTimeoutInMilliseconds, keepAliveIntervalInMilliseconds, statefulReconnectBufferSize);
|
|
2782
|
+
}
|
|
2783
|
+
constructor(connection, logger, protocol, reconnectPolicy, serverTimeoutInMilliseconds, keepAliveIntervalInMilliseconds, statefulReconnectBufferSize) {
|
|
2784
|
+
this._nextKeepAlive = 0;
|
|
2785
|
+
this._freezeEventListener = () => {
|
|
2786
|
+
this._logger.log(LogLevel.Warning, "The page is being frozen, this will likely lead to the connection being closed and messages being lost. For more information see the docs at https://learn.microsoft.com/aspnet/core/signalr/javascript-client#bsleep");
|
|
2787
|
+
};
|
|
2788
|
+
Arg.isRequired(connection, "connection");
|
|
2789
|
+
Arg.isRequired(logger, "logger");
|
|
2790
|
+
Arg.isRequired(protocol, "protocol");
|
|
2791
|
+
this.serverTimeoutInMilliseconds = serverTimeoutInMilliseconds !== null && serverTimeoutInMilliseconds !== void 0 ? serverTimeoutInMilliseconds : DEFAULT_TIMEOUT_IN_MS;
|
|
2792
|
+
this.keepAliveIntervalInMilliseconds = keepAliveIntervalInMilliseconds !== null && keepAliveIntervalInMilliseconds !== void 0 ? keepAliveIntervalInMilliseconds : DEFAULT_PING_INTERVAL_IN_MS;
|
|
2793
|
+
this._statefulReconnectBufferSize = statefulReconnectBufferSize !== null && statefulReconnectBufferSize !== void 0 ? statefulReconnectBufferSize : DEFAULT_STATEFUL_RECONNECT_BUFFER_SIZE;
|
|
2794
|
+
this._logger = logger;
|
|
2795
|
+
this._protocol = protocol;
|
|
2796
|
+
this.connection = connection;
|
|
2797
|
+
this._reconnectPolicy = reconnectPolicy;
|
|
2798
|
+
this._handshakeProtocol = new HandshakeProtocol();
|
|
2799
|
+
this.connection.onreceive = (data) => this._processIncomingData(data);
|
|
2800
|
+
this.connection.onclose = (error) => this._connectionClosed(error);
|
|
2801
|
+
this._callbacks = {};
|
|
2802
|
+
this._methods = {};
|
|
2803
|
+
this._closedCallbacks = [];
|
|
2804
|
+
this._reconnectingCallbacks = [];
|
|
2805
|
+
this._reconnectedCallbacks = [];
|
|
2806
|
+
this._invocationId = 0;
|
|
2807
|
+
this._receivedHandshakeResponse = false;
|
|
2808
|
+
this._connectionState = HubConnectionState.Disconnected;
|
|
2809
|
+
this._connectionStarted = false;
|
|
2810
|
+
this._cachedPingMessage = this._protocol.writeMessage({ type: MessageType.Ping });
|
|
2811
|
+
}
|
|
2812
|
+
/** Indicates the state of the {@link HubConnection} to the server. */
|
|
2813
|
+
get state() {
|
|
2814
|
+
return this._connectionState;
|
|
2815
|
+
}
|
|
2816
|
+
/** Represents the connection id of the {@link HubConnection} on the server. The connection id will be null when the connection is either
|
|
2817
|
+
* in the disconnected state or if the negotiation step was skipped.
|
|
2818
|
+
*/
|
|
2819
|
+
get connectionId() {
|
|
2820
|
+
return this.connection ? this.connection.connectionId || null : null;
|
|
2821
|
+
}
|
|
2822
|
+
/** Indicates the url of the {@link HubConnection} to the server. */
|
|
2823
|
+
get baseUrl() {
|
|
2824
|
+
return this.connection.baseUrl || "";
|
|
2825
|
+
}
|
|
2826
|
+
/**
|
|
2827
|
+
* Sets a new url for the HubConnection. Note that the url can only be changed when the connection is in either the Disconnected or
|
|
2828
|
+
* Reconnecting states.
|
|
2829
|
+
* @param {string} url The url to connect to.
|
|
2830
|
+
*/
|
|
2831
|
+
set baseUrl(url) {
|
|
2832
|
+
if (this._connectionState !== HubConnectionState.Disconnected && this._connectionState !== HubConnectionState.Reconnecting) {
|
|
2833
|
+
throw new Error("The HubConnection must be in the Disconnected or Reconnecting state to change the url.");
|
|
2834
|
+
}
|
|
2835
|
+
if (!url) {
|
|
2836
|
+
throw new Error("The HubConnection url must be a valid url.");
|
|
2837
|
+
}
|
|
2838
|
+
this.connection.baseUrl = url;
|
|
2839
|
+
}
|
|
2840
|
+
/** Starts the connection.
|
|
2841
|
+
*
|
|
2842
|
+
* @returns {Promise<void>} A Promise that resolves when the connection has been successfully established, or rejects with an error.
|
|
2843
|
+
*/
|
|
2844
|
+
start() {
|
|
2845
|
+
this._startPromise = this._startWithStateTransitions();
|
|
2846
|
+
return this._startPromise;
|
|
2847
|
+
}
|
|
2848
|
+
async _startWithStateTransitions() {
|
|
2849
|
+
if (this._connectionState !== HubConnectionState.Disconnected) {
|
|
2850
|
+
return Promise.reject(new Error("Cannot start a HubConnection that is not in the 'Disconnected' state."));
|
|
2851
|
+
}
|
|
2852
|
+
this._connectionState = HubConnectionState.Connecting;
|
|
2853
|
+
this._logger.log(LogLevel.Debug, "Starting HubConnection.");
|
|
2854
|
+
try {
|
|
2855
|
+
await this._startInternal();
|
|
2856
|
+
if (Platform.isBrowser) {
|
|
2857
|
+
window.document.addEventListener("freeze", this._freezeEventListener);
|
|
2858
|
+
}
|
|
2859
|
+
this._connectionState = HubConnectionState.Connected;
|
|
2860
|
+
this._connectionStarted = true;
|
|
2861
|
+
this._logger.log(LogLevel.Debug, "HubConnection connected successfully.");
|
|
2862
|
+
} catch (e) {
|
|
2863
|
+
this._connectionState = HubConnectionState.Disconnected;
|
|
2864
|
+
this._logger.log(LogLevel.Debug, `HubConnection failed to start successfully because of error '${e}'.`);
|
|
2865
|
+
return Promise.reject(e);
|
|
2866
|
+
}
|
|
2867
|
+
}
|
|
2868
|
+
async _startInternal() {
|
|
2869
|
+
this._stopDuringStartError = void 0;
|
|
2870
|
+
this._receivedHandshakeResponse = false;
|
|
2871
|
+
const handshakePromise = new Promise((resolve, reject) => {
|
|
2872
|
+
this._handshakeResolver = resolve;
|
|
2873
|
+
this._handshakeRejecter = reject;
|
|
2874
|
+
});
|
|
2875
|
+
await this.connection.start(this._protocol.transferFormat);
|
|
2876
|
+
try {
|
|
2877
|
+
let version = this._protocol.version;
|
|
2878
|
+
if (!this.connection.features.reconnect) {
|
|
2879
|
+
version = 1;
|
|
2880
|
+
}
|
|
2881
|
+
const handshakeRequest = {
|
|
2882
|
+
protocol: this._protocol.name,
|
|
2883
|
+
version
|
|
2884
|
+
};
|
|
2885
|
+
this._logger.log(LogLevel.Debug, "Sending handshake request.");
|
|
2886
|
+
await this._sendMessage(this._handshakeProtocol.writeHandshakeRequest(handshakeRequest));
|
|
2887
|
+
this._logger.log(LogLevel.Information, `Using HubProtocol '${this._protocol.name}'.`);
|
|
2888
|
+
this._cleanupTimeout();
|
|
2889
|
+
this._resetTimeoutPeriod();
|
|
2890
|
+
this._resetKeepAliveInterval();
|
|
2891
|
+
await handshakePromise;
|
|
2892
|
+
if (this._stopDuringStartError) {
|
|
2893
|
+
throw this._stopDuringStartError;
|
|
2894
|
+
}
|
|
2895
|
+
const useStatefulReconnect = this.connection.features.reconnect || false;
|
|
2896
|
+
if (useStatefulReconnect) {
|
|
2897
|
+
this._messageBuffer = new MessageBuffer(this._protocol, this.connection, this._statefulReconnectBufferSize);
|
|
2898
|
+
this.connection.features.disconnected = this._messageBuffer._disconnected.bind(this._messageBuffer);
|
|
2899
|
+
this.connection.features.resend = () => {
|
|
2900
|
+
if (this._messageBuffer) {
|
|
2901
|
+
return this._messageBuffer._resend();
|
|
2902
|
+
}
|
|
2903
|
+
};
|
|
2904
|
+
}
|
|
2905
|
+
if (!this.connection.features.inherentKeepAlive) {
|
|
2906
|
+
await this._sendMessage(this._cachedPingMessage);
|
|
2907
|
+
}
|
|
2908
|
+
} catch (e) {
|
|
2909
|
+
this._logger.log(LogLevel.Debug, `Hub handshake failed with error '${e}' during start(). Stopping HubConnection.`);
|
|
2910
|
+
this._cleanupTimeout();
|
|
2911
|
+
this._cleanupPingTimer();
|
|
2912
|
+
await this.connection.stop(e);
|
|
2913
|
+
throw e;
|
|
2914
|
+
}
|
|
2915
|
+
}
|
|
2916
|
+
/** Stops the connection.
|
|
2917
|
+
*
|
|
2918
|
+
* @returns {Promise<void>} A Promise that resolves when the connection has been successfully terminated, or rejects with an error.
|
|
2919
|
+
*/
|
|
2920
|
+
async stop() {
|
|
2921
|
+
const startPromise = this._startPromise;
|
|
2922
|
+
this.connection.features.reconnect = false;
|
|
2923
|
+
this._stopPromise = this._stopInternal();
|
|
2924
|
+
await this._stopPromise;
|
|
2925
|
+
try {
|
|
2926
|
+
await startPromise;
|
|
2927
|
+
} catch (e) {
|
|
2928
|
+
}
|
|
2929
|
+
}
|
|
2930
|
+
_stopInternal(error) {
|
|
2931
|
+
if (this._connectionState === HubConnectionState.Disconnected) {
|
|
2932
|
+
this._logger.log(LogLevel.Debug, `Call to HubConnection.stop(${error}) ignored because it is already in the disconnected state.`);
|
|
2933
|
+
return Promise.resolve();
|
|
2934
|
+
}
|
|
2935
|
+
if (this._connectionState === HubConnectionState.Disconnecting) {
|
|
2936
|
+
this._logger.log(LogLevel.Debug, `Call to HttpConnection.stop(${error}) ignored because the connection is already in the disconnecting state.`);
|
|
2937
|
+
return this._stopPromise;
|
|
2938
|
+
}
|
|
2939
|
+
const state = this._connectionState;
|
|
2940
|
+
this._connectionState = HubConnectionState.Disconnecting;
|
|
2941
|
+
this._logger.log(LogLevel.Debug, "Stopping HubConnection.");
|
|
2942
|
+
if (this._reconnectDelayHandle) {
|
|
2943
|
+
this._logger.log(LogLevel.Debug, "Connection stopped during reconnect delay. Done reconnecting.");
|
|
2944
|
+
clearTimeout(this._reconnectDelayHandle);
|
|
2945
|
+
this._reconnectDelayHandle = void 0;
|
|
2946
|
+
this._completeClose();
|
|
2947
|
+
return Promise.resolve();
|
|
2948
|
+
}
|
|
2949
|
+
if (state === HubConnectionState.Connected) {
|
|
2950
|
+
this._sendCloseMessage();
|
|
2951
|
+
}
|
|
2952
|
+
this._cleanupTimeout();
|
|
2953
|
+
this._cleanupPingTimer();
|
|
2954
|
+
this._stopDuringStartError = error || new AbortError("The connection was stopped before the hub handshake could complete.");
|
|
2955
|
+
return this.connection.stop(error);
|
|
2956
|
+
}
|
|
2957
|
+
async _sendCloseMessage() {
|
|
2958
|
+
try {
|
|
2959
|
+
await this._sendWithProtocol(this._createCloseMessage());
|
|
2960
|
+
} catch {
|
|
2961
|
+
}
|
|
2962
|
+
}
|
|
2963
|
+
/** Invokes a streaming hub method on the server using the specified name and arguments.
|
|
2964
|
+
*
|
|
2965
|
+
* @typeparam T The type of the items returned by the server.
|
|
2966
|
+
* @param {string} methodName The name of the server method to invoke.
|
|
2967
|
+
* @param {any[]} args The arguments used to invoke the server method.
|
|
2968
|
+
* @returns {IStreamResult<T>} An object that yields results from the server as they are received.
|
|
2969
|
+
*/
|
|
2970
|
+
stream(methodName, ...args) {
|
|
2971
|
+
const [streams, streamIds] = this._replaceStreamingParams(args);
|
|
2972
|
+
const invocationDescriptor = this._createStreamInvocation(methodName, args, streamIds);
|
|
2973
|
+
let promiseQueue;
|
|
2974
|
+
const subject = new Subject();
|
|
2975
|
+
subject.cancelCallback = () => {
|
|
2976
|
+
const cancelInvocation = this._createCancelInvocation(invocationDescriptor.invocationId);
|
|
2977
|
+
delete this._callbacks[invocationDescriptor.invocationId];
|
|
2978
|
+
return promiseQueue.then(() => {
|
|
2979
|
+
return this._sendWithProtocol(cancelInvocation);
|
|
2980
|
+
});
|
|
2981
|
+
};
|
|
2982
|
+
this._callbacks[invocationDescriptor.invocationId] = (invocationEvent, error) => {
|
|
2983
|
+
if (error) {
|
|
2984
|
+
subject.error(error);
|
|
2985
|
+
return;
|
|
2986
|
+
} else if (invocationEvent) {
|
|
2987
|
+
if (invocationEvent.type === MessageType.Completion) {
|
|
2988
|
+
if (invocationEvent.error) {
|
|
2989
|
+
subject.error(new Error(invocationEvent.error));
|
|
2990
|
+
} else {
|
|
2991
|
+
subject.complete();
|
|
2992
|
+
}
|
|
2993
|
+
} else {
|
|
2994
|
+
subject.next(invocationEvent.item);
|
|
2995
|
+
}
|
|
2996
|
+
}
|
|
2997
|
+
};
|
|
2998
|
+
promiseQueue = this._sendWithProtocol(invocationDescriptor).catch((e) => {
|
|
2999
|
+
subject.error(e);
|
|
3000
|
+
delete this._callbacks[invocationDescriptor.invocationId];
|
|
3001
|
+
});
|
|
3002
|
+
this._launchStreams(streams, promiseQueue);
|
|
3003
|
+
return subject;
|
|
3004
|
+
}
|
|
3005
|
+
_sendMessage(message) {
|
|
3006
|
+
this._resetKeepAliveInterval();
|
|
3007
|
+
return this.connection.send(message);
|
|
3008
|
+
}
|
|
3009
|
+
/**
|
|
3010
|
+
* Sends a js object to the server.
|
|
3011
|
+
* @param message The js object to serialize and send.
|
|
3012
|
+
*/
|
|
3013
|
+
_sendWithProtocol(message) {
|
|
3014
|
+
if (this._messageBuffer) {
|
|
3015
|
+
return this._messageBuffer._send(message);
|
|
3016
|
+
} else {
|
|
3017
|
+
return this._sendMessage(this._protocol.writeMessage(message));
|
|
3018
|
+
}
|
|
3019
|
+
}
|
|
3020
|
+
/** Invokes a hub method on the server using the specified name and arguments. Does not wait for a response from the receiver.
|
|
3021
|
+
*
|
|
3022
|
+
* The Promise returned by this method resolves when the client has sent the invocation to the server. The server may still
|
|
3023
|
+
* be processing the invocation.
|
|
3024
|
+
*
|
|
3025
|
+
* @param {string} methodName The name of the server method to invoke.
|
|
3026
|
+
* @param {any[]} args The arguments used to invoke the server method.
|
|
3027
|
+
* @returns {Promise<void>} A Promise that resolves when the invocation has been successfully sent, or rejects with an error.
|
|
3028
|
+
*/
|
|
3029
|
+
send(methodName, ...args) {
|
|
3030
|
+
const [streams, streamIds] = this._replaceStreamingParams(args);
|
|
3031
|
+
const sendPromise = this._sendWithProtocol(this._createInvocation(methodName, args, true, streamIds));
|
|
3032
|
+
this._launchStreams(streams, sendPromise);
|
|
3033
|
+
return sendPromise;
|
|
3034
|
+
}
|
|
3035
|
+
/** Invokes a hub method on the server using the specified name and arguments.
|
|
3036
|
+
*
|
|
3037
|
+
* The Promise returned by this method resolves when the server indicates it has finished invoking the method. When the promise
|
|
3038
|
+
* resolves, the server has finished invoking the method. If the server method returns a result, it is produced as the result of
|
|
3039
|
+
* resolving the Promise.
|
|
3040
|
+
*
|
|
3041
|
+
* @typeparam T The expected return type.
|
|
3042
|
+
* @param {string} methodName The name of the server method to invoke.
|
|
3043
|
+
* @param {any[]} args The arguments used to invoke the server method.
|
|
3044
|
+
* @returns {Promise<T>} A Promise that resolves with the result of the server method (if any), or rejects with an error.
|
|
3045
|
+
*/
|
|
3046
|
+
invoke(methodName, ...args) {
|
|
3047
|
+
const [streams, streamIds] = this._replaceStreamingParams(args);
|
|
3048
|
+
const invocationDescriptor = this._createInvocation(methodName, args, false, streamIds);
|
|
3049
|
+
const p = new Promise((resolve, reject) => {
|
|
3050
|
+
this._callbacks[invocationDescriptor.invocationId] = (invocationEvent, error) => {
|
|
3051
|
+
if (error) {
|
|
3052
|
+
reject(error);
|
|
3053
|
+
return;
|
|
3054
|
+
} else if (invocationEvent) {
|
|
3055
|
+
if (invocationEvent.type === MessageType.Completion) {
|
|
3056
|
+
if (invocationEvent.error) {
|
|
3057
|
+
reject(new Error(invocationEvent.error));
|
|
3058
|
+
} else {
|
|
3059
|
+
resolve(invocationEvent.result);
|
|
3060
|
+
}
|
|
3061
|
+
} else {
|
|
3062
|
+
reject(new Error(`Unexpected message type: ${invocationEvent.type}`));
|
|
3063
|
+
}
|
|
3064
|
+
}
|
|
3065
|
+
};
|
|
3066
|
+
const promiseQueue = this._sendWithProtocol(invocationDescriptor).catch((e) => {
|
|
3067
|
+
reject(e);
|
|
3068
|
+
delete this._callbacks[invocationDescriptor.invocationId];
|
|
3069
|
+
});
|
|
3070
|
+
this._launchStreams(streams, promiseQueue);
|
|
3071
|
+
});
|
|
3072
|
+
return p;
|
|
3073
|
+
}
|
|
3074
|
+
on(methodName, newMethod) {
|
|
3075
|
+
if (!methodName || !newMethod) {
|
|
3076
|
+
return;
|
|
3077
|
+
}
|
|
3078
|
+
methodName = methodName.toLowerCase();
|
|
3079
|
+
if (!this._methods[methodName]) {
|
|
3080
|
+
this._methods[methodName] = [];
|
|
3081
|
+
}
|
|
3082
|
+
if (this._methods[methodName].indexOf(newMethod) !== -1) {
|
|
3083
|
+
return;
|
|
3084
|
+
}
|
|
3085
|
+
this._methods[methodName].push(newMethod);
|
|
3086
|
+
}
|
|
3087
|
+
off(methodName, method) {
|
|
3088
|
+
if (!methodName) {
|
|
3089
|
+
return;
|
|
3090
|
+
}
|
|
3091
|
+
methodName = methodName.toLowerCase();
|
|
3092
|
+
const handlers = this._methods[methodName];
|
|
3093
|
+
if (!handlers) {
|
|
3094
|
+
return;
|
|
3095
|
+
}
|
|
3096
|
+
if (method) {
|
|
3097
|
+
const removeIdx = handlers.indexOf(method);
|
|
3098
|
+
if (removeIdx !== -1) {
|
|
3099
|
+
handlers.splice(removeIdx, 1);
|
|
3100
|
+
if (handlers.length === 0) {
|
|
3101
|
+
delete this._methods[methodName];
|
|
3102
|
+
}
|
|
3103
|
+
}
|
|
3104
|
+
} else {
|
|
3105
|
+
delete this._methods[methodName];
|
|
3106
|
+
}
|
|
3107
|
+
}
|
|
3108
|
+
/** Registers a handler that will be invoked when the connection is closed.
|
|
3109
|
+
*
|
|
3110
|
+
* @param {Function} callback The handler that will be invoked when the connection is closed. Optionally receives a single argument containing the error that caused the connection to close (if any).
|
|
3111
|
+
*/
|
|
3112
|
+
onclose(callback) {
|
|
3113
|
+
if (callback) {
|
|
3114
|
+
this._closedCallbacks.push(callback);
|
|
3115
|
+
}
|
|
3116
|
+
}
|
|
3117
|
+
/** Registers a handler that will be invoked when the connection starts reconnecting.
|
|
3118
|
+
*
|
|
3119
|
+
* @param {Function} callback The handler that will be invoked when the connection starts reconnecting. Optionally receives a single argument containing the error that caused the connection to start reconnecting (if any).
|
|
3120
|
+
*/
|
|
3121
|
+
onreconnecting(callback) {
|
|
3122
|
+
if (callback) {
|
|
3123
|
+
this._reconnectingCallbacks.push(callback);
|
|
3124
|
+
}
|
|
3125
|
+
}
|
|
3126
|
+
/** Registers a handler that will be invoked when the connection successfully reconnects.
|
|
3127
|
+
*
|
|
3128
|
+
* @param {Function} callback The handler that will be invoked when the connection successfully reconnects.
|
|
3129
|
+
*/
|
|
3130
|
+
onreconnected(callback) {
|
|
3131
|
+
if (callback) {
|
|
3132
|
+
this._reconnectedCallbacks.push(callback);
|
|
3133
|
+
}
|
|
3134
|
+
}
|
|
3135
|
+
_processIncomingData(data) {
|
|
3136
|
+
this._cleanupTimeout();
|
|
3137
|
+
if (!this._receivedHandshakeResponse) {
|
|
3138
|
+
data = this._processHandshakeResponse(data);
|
|
3139
|
+
this._receivedHandshakeResponse = true;
|
|
3140
|
+
}
|
|
3141
|
+
if (data) {
|
|
3142
|
+
const messages = this._protocol.parseMessages(data, this._logger);
|
|
3143
|
+
for (const message of messages) {
|
|
3144
|
+
if (this._messageBuffer && !this._messageBuffer._shouldProcessMessage(message)) {
|
|
3145
|
+
continue;
|
|
3146
|
+
}
|
|
3147
|
+
switch (message.type) {
|
|
3148
|
+
case MessageType.Invocation:
|
|
3149
|
+
this._invokeClientMethod(message).catch((e) => {
|
|
3150
|
+
this._logger.log(LogLevel.Error, `Invoke client method threw error: ${getErrorString(e)}`);
|
|
3151
|
+
});
|
|
3152
|
+
break;
|
|
3153
|
+
case MessageType.StreamItem:
|
|
3154
|
+
case MessageType.Completion: {
|
|
3155
|
+
const callback = this._callbacks[message.invocationId];
|
|
3156
|
+
if (callback) {
|
|
3157
|
+
if (message.type === MessageType.Completion) {
|
|
3158
|
+
delete this._callbacks[message.invocationId];
|
|
3159
|
+
}
|
|
3160
|
+
try {
|
|
3161
|
+
callback(message);
|
|
3162
|
+
} catch (e) {
|
|
3163
|
+
this._logger.log(LogLevel.Error, `Stream callback threw error: ${getErrorString(e)}`);
|
|
3164
|
+
}
|
|
3165
|
+
}
|
|
3166
|
+
break;
|
|
3167
|
+
}
|
|
3168
|
+
case MessageType.Ping:
|
|
3169
|
+
break;
|
|
3170
|
+
case MessageType.Close: {
|
|
3171
|
+
this._logger.log(LogLevel.Information, "Close message received from server.");
|
|
3172
|
+
const error = message.error ? new Error("Server returned an error on close: " + message.error) : void 0;
|
|
3173
|
+
if (message.allowReconnect === true) {
|
|
3174
|
+
this.connection.stop(error);
|
|
3175
|
+
} else {
|
|
3176
|
+
this._stopPromise = this._stopInternal(error);
|
|
3177
|
+
}
|
|
3178
|
+
break;
|
|
3179
|
+
}
|
|
3180
|
+
case MessageType.Ack:
|
|
3181
|
+
if (this._messageBuffer) {
|
|
3182
|
+
this._messageBuffer._ack(message);
|
|
3183
|
+
}
|
|
3184
|
+
break;
|
|
3185
|
+
case MessageType.Sequence:
|
|
3186
|
+
if (this._messageBuffer) {
|
|
3187
|
+
this._messageBuffer._resetSequence(message);
|
|
3188
|
+
}
|
|
3189
|
+
break;
|
|
3190
|
+
default:
|
|
3191
|
+
this._logger.log(LogLevel.Warning, `Invalid message type: ${message.type}.`);
|
|
3192
|
+
break;
|
|
3193
|
+
}
|
|
3194
|
+
}
|
|
3195
|
+
}
|
|
3196
|
+
this._resetTimeoutPeriod();
|
|
3197
|
+
}
|
|
3198
|
+
_processHandshakeResponse(data) {
|
|
3199
|
+
let responseMessage;
|
|
3200
|
+
let remainingData;
|
|
3201
|
+
try {
|
|
3202
|
+
[remainingData, responseMessage] = this._handshakeProtocol.parseHandshakeResponse(data);
|
|
3203
|
+
} catch (e) {
|
|
3204
|
+
const message = "Error parsing handshake response: " + e;
|
|
3205
|
+
this._logger.log(LogLevel.Error, message);
|
|
3206
|
+
const error = new Error(message);
|
|
3207
|
+
this._handshakeRejecter(error);
|
|
3208
|
+
throw error;
|
|
3209
|
+
}
|
|
3210
|
+
if (responseMessage.error) {
|
|
3211
|
+
const message = "Server returned handshake error: " + responseMessage.error;
|
|
3212
|
+
this._logger.log(LogLevel.Error, message);
|
|
3213
|
+
const error = new Error(message);
|
|
3214
|
+
this._handshakeRejecter(error);
|
|
3215
|
+
throw error;
|
|
3216
|
+
} else {
|
|
3217
|
+
this._logger.log(LogLevel.Debug, "Server handshake complete.");
|
|
3218
|
+
}
|
|
3219
|
+
this._handshakeResolver();
|
|
3220
|
+
return remainingData;
|
|
3221
|
+
}
|
|
3222
|
+
_resetKeepAliveInterval() {
|
|
3223
|
+
if (this.connection.features.inherentKeepAlive) {
|
|
3224
|
+
return;
|
|
3225
|
+
}
|
|
3226
|
+
this._nextKeepAlive = (/* @__PURE__ */ new Date()).getTime() + this.keepAliveIntervalInMilliseconds;
|
|
3227
|
+
this._cleanupPingTimer();
|
|
3228
|
+
}
|
|
3229
|
+
_resetTimeoutPeriod() {
|
|
3230
|
+
if (!this.connection.features || !this.connection.features.inherentKeepAlive) {
|
|
3231
|
+
this._timeoutHandle = setTimeout(() => this.serverTimeout(), this.serverTimeoutInMilliseconds);
|
|
3232
|
+
if (this._pingServerHandle === void 0) {
|
|
3233
|
+
let nextPing = this._nextKeepAlive - (/* @__PURE__ */ new Date()).getTime();
|
|
3234
|
+
if (nextPing < 0) {
|
|
3235
|
+
nextPing = 0;
|
|
3236
|
+
}
|
|
3237
|
+
this._pingServerHandle = setTimeout(async () => {
|
|
3238
|
+
if (this._connectionState === HubConnectionState.Connected) {
|
|
3239
|
+
try {
|
|
3240
|
+
await this._sendMessage(this._cachedPingMessage);
|
|
3241
|
+
} catch {
|
|
3242
|
+
this._cleanupPingTimer();
|
|
3243
|
+
}
|
|
3244
|
+
}
|
|
3245
|
+
}, nextPing);
|
|
3246
|
+
}
|
|
3247
|
+
}
|
|
3248
|
+
}
|
|
3249
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
3250
|
+
serverTimeout() {
|
|
3251
|
+
this.connection.stop(new Error("Server timeout elapsed without receiving a message from the server."));
|
|
3252
|
+
}
|
|
3253
|
+
async _invokeClientMethod(invocationMessage) {
|
|
3254
|
+
const methodName = invocationMessage.target.toLowerCase();
|
|
3255
|
+
const methods = this._methods[methodName];
|
|
3256
|
+
if (!methods) {
|
|
3257
|
+
this._logger.log(LogLevel.Warning, `No client method with the name '${methodName}' found.`);
|
|
3258
|
+
if (invocationMessage.invocationId) {
|
|
3259
|
+
this._logger.log(LogLevel.Warning, `No result given for '${methodName}' method and invocation ID '${invocationMessage.invocationId}'.`);
|
|
3260
|
+
await this._sendWithProtocol(this._createCompletionMessage(invocationMessage.invocationId, "Client didn't provide a result.", null));
|
|
3261
|
+
}
|
|
3262
|
+
return;
|
|
3263
|
+
}
|
|
3264
|
+
const methodsCopy = methods.slice();
|
|
3265
|
+
const expectsResponse = invocationMessage.invocationId ? true : false;
|
|
3266
|
+
let res;
|
|
3267
|
+
let exception;
|
|
3268
|
+
let completionMessage;
|
|
3269
|
+
for (const m of methodsCopy) {
|
|
3270
|
+
try {
|
|
3271
|
+
const prevRes = res;
|
|
3272
|
+
res = await m.apply(this, invocationMessage.arguments);
|
|
3273
|
+
if (expectsResponse && res && prevRes) {
|
|
3274
|
+
this._logger.log(LogLevel.Error, `Multiple results provided for '${methodName}'. Sending error to server.`);
|
|
3275
|
+
completionMessage = this._createCompletionMessage(invocationMessage.invocationId, `Client provided multiple results.`, null);
|
|
3276
|
+
}
|
|
3277
|
+
exception = void 0;
|
|
3278
|
+
} catch (e) {
|
|
3279
|
+
exception = e;
|
|
3280
|
+
this._logger.log(LogLevel.Error, `A callback for the method '${methodName}' threw error '${e}'.`);
|
|
3281
|
+
}
|
|
3282
|
+
}
|
|
3283
|
+
if (completionMessage) {
|
|
3284
|
+
await this._sendWithProtocol(completionMessage);
|
|
3285
|
+
} else if (expectsResponse) {
|
|
3286
|
+
if (exception) {
|
|
3287
|
+
completionMessage = this._createCompletionMessage(invocationMessage.invocationId, `${exception}`, null);
|
|
3288
|
+
} else if (res !== void 0) {
|
|
3289
|
+
completionMessage = this._createCompletionMessage(invocationMessage.invocationId, null, res);
|
|
3290
|
+
} else {
|
|
3291
|
+
this._logger.log(LogLevel.Warning, `No result given for '${methodName}' method and invocation ID '${invocationMessage.invocationId}'.`);
|
|
3292
|
+
completionMessage = this._createCompletionMessage(invocationMessage.invocationId, "Client didn't provide a result.", null);
|
|
3293
|
+
}
|
|
3294
|
+
await this._sendWithProtocol(completionMessage);
|
|
3295
|
+
} else {
|
|
3296
|
+
if (res) {
|
|
3297
|
+
this._logger.log(LogLevel.Error, `Result given for '${methodName}' method but server is not expecting a result.`);
|
|
3298
|
+
}
|
|
3299
|
+
}
|
|
3300
|
+
}
|
|
3301
|
+
_connectionClosed(error) {
|
|
3302
|
+
this._logger.log(LogLevel.Debug, `HubConnection.connectionClosed(${error}) called while in state ${this._connectionState}.`);
|
|
3303
|
+
this._stopDuringStartError = this._stopDuringStartError || error || new AbortError("The underlying connection was closed before the hub handshake could complete.");
|
|
3304
|
+
if (this._handshakeResolver) {
|
|
3305
|
+
this._handshakeResolver();
|
|
3306
|
+
}
|
|
3307
|
+
this._cancelCallbacksWithError(error || new Error("Invocation canceled due to the underlying connection being closed."));
|
|
3308
|
+
this._cleanupTimeout();
|
|
3309
|
+
this._cleanupPingTimer();
|
|
3310
|
+
if (this._connectionState === HubConnectionState.Disconnecting) {
|
|
3311
|
+
this._completeClose(error);
|
|
3312
|
+
} else if (this._connectionState === HubConnectionState.Connected && this._reconnectPolicy) {
|
|
3313
|
+
this._reconnect(error);
|
|
3314
|
+
} else if (this._connectionState === HubConnectionState.Connected) {
|
|
3315
|
+
this._completeClose(error);
|
|
3316
|
+
}
|
|
3317
|
+
}
|
|
3318
|
+
_completeClose(error) {
|
|
3319
|
+
if (this._connectionStarted) {
|
|
3320
|
+
this._connectionState = HubConnectionState.Disconnected;
|
|
3321
|
+
this._connectionStarted = false;
|
|
3322
|
+
if (this._messageBuffer) {
|
|
3323
|
+
this._messageBuffer._dispose(error !== null && error !== void 0 ? error : new Error("Connection closed."));
|
|
3324
|
+
this._messageBuffer = void 0;
|
|
3325
|
+
}
|
|
3326
|
+
if (Platform.isBrowser) {
|
|
3327
|
+
window.document.removeEventListener("freeze", this._freezeEventListener);
|
|
3328
|
+
}
|
|
3329
|
+
try {
|
|
3330
|
+
this._closedCallbacks.forEach((c) => c.apply(this, [error]));
|
|
3331
|
+
} catch (e) {
|
|
3332
|
+
this._logger.log(LogLevel.Error, `An onclose callback called with error '${error}' threw error '${e}'.`);
|
|
3333
|
+
}
|
|
3334
|
+
}
|
|
3335
|
+
}
|
|
3336
|
+
async _reconnect(error) {
|
|
3337
|
+
const reconnectStartTime = Date.now();
|
|
3338
|
+
let previousReconnectAttempts = 0;
|
|
3339
|
+
let retryError = error !== void 0 ? error : new Error("Attempting to reconnect due to a unknown error.");
|
|
3340
|
+
let nextRetryDelay = this._getNextRetryDelay(previousReconnectAttempts++, 0, retryError);
|
|
3341
|
+
if (nextRetryDelay === null) {
|
|
3342
|
+
this._logger.log(LogLevel.Debug, "Connection not reconnecting because the IRetryPolicy returned null on the first reconnect attempt.");
|
|
3343
|
+
this._completeClose(error);
|
|
3344
|
+
return;
|
|
3345
|
+
}
|
|
3346
|
+
this._connectionState = HubConnectionState.Reconnecting;
|
|
3347
|
+
if (error) {
|
|
3348
|
+
this._logger.log(LogLevel.Information, `Connection reconnecting because of error '${error}'.`);
|
|
3349
|
+
} else {
|
|
3350
|
+
this._logger.log(LogLevel.Information, "Connection reconnecting.");
|
|
3351
|
+
}
|
|
3352
|
+
if (this._reconnectingCallbacks.length !== 0) {
|
|
3353
|
+
try {
|
|
3354
|
+
this._reconnectingCallbacks.forEach((c) => c.apply(this, [error]));
|
|
3355
|
+
} catch (e) {
|
|
3356
|
+
this._logger.log(LogLevel.Error, `An onreconnecting callback called with error '${error}' threw error '${e}'.`);
|
|
3357
|
+
}
|
|
3358
|
+
if (this._connectionState !== HubConnectionState.Reconnecting) {
|
|
3359
|
+
this._logger.log(LogLevel.Debug, "Connection left the reconnecting state in onreconnecting callback. Done reconnecting.");
|
|
3360
|
+
return;
|
|
3361
|
+
}
|
|
3362
|
+
}
|
|
3363
|
+
while (nextRetryDelay !== null) {
|
|
3364
|
+
this._logger.log(LogLevel.Information, `Reconnect attempt number ${previousReconnectAttempts} will start in ${nextRetryDelay} ms.`);
|
|
3365
|
+
await new Promise((resolve) => {
|
|
3366
|
+
this._reconnectDelayHandle = setTimeout(resolve, nextRetryDelay);
|
|
3367
|
+
});
|
|
3368
|
+
this._reconnectDelayHandle = void 0;
|
|
3369
|
+
if (this._connectionState !== HubConnectionState.Reconnecting) {
|
|
3370
|
+
this._logger.log(LogLevel.Debug, "Connection left the reconnecting state during reconnect delay. Done reconnecting.");
|
|
3371
|
+
return;
|
|
3372
|
+
}
|
|
3373
|
+
try {
|
|
3374
|
+
await this._startInternal();
|
|
3375
|
+
this._connectionState = HubConnectionState.Connected;
|
|
3376
|
+
this._logger.log(LogLevel.Information, "HubConnection reconnected successfully.");
|
|
3377
|
+
if (this._reconnectedCallbacks.length !== 0) {
|
|
3378
|
+
try {
|
|
3379
|
+
this._reconnectedCallbacks.forEach((c) => c.apply(this, [this.connection.connectionId]));
|
|
3380
|
+
} catch (e) {
|
|
3381
|
+
this._logger.log(LogLevel.Error, `An onreconnected callback called with connectionId '${this.connection.connectionId}; threw error '${e}'.`);
|
|
3382
|
+
}
|
|
3383
|
+
}
|
|
3384
|
+
return;
|
|
3385
|
+
} catch (e) {
|
|
3386
|
+
this._logger.log(LogLevel.Information, `Reconnect attempt failed because of error '${e}'.`);
|
|
3387
|
+
if (this._connectionState !== HubConnectionState.Reconnecting) {
|
|
3388
|
+
this._logger.log(LogLevel.Debug, `Connection moved to the '${this._connectionState}' from the reconnecting state during reconnect attempt. Done reconnecting.`);
|
|
3389
|
+
if (this._connectionState === HubConnectionState.Disconnecting) {
|
|
3390
|
+
this._completeClose();
|
|
3391
|
+
}
|
|
3392
|
+
return;
|
|
3393
|
+
}
|
|
3394
|
+
retryError = e instanceof Error ? e : new Error(e.toString());
|
|
3395
|
+
nextRetryDelay = this._getNextRetryDelay(previousReconnectAttempts++, Date.now() - reconnectStartTime, retryError);
|
|
3396
|
+
}
|
|
3397
|
+
}
|
|
3398
|
+
this._logger.log(LogLevel.Information, `Reconnect retries have been exhausted after ${Date.now() - reconnectStartTime} ms and ${previousReconnectAttempts} failed attempts. Connection disconnecting.`);
|
|
3399
|
+
this._completeClose();
|
|
3400
|
+
}
|
|
3401
|
+
_getNextRetryDelay(previousRetryCount, elapsedMilliseconds, retryReason) {
|
|
3402
|
+
try {
|
|
3403
|
+
return this._reconnectPolicy.nextRetryDelayInMilliseconds({
|
|
3404
|
+
elapsedMilliseconds,
|
|
3405
|
+
previousRetryCount,
|
|
3406
|
+
retryReason
|
|
3407
|
+
});
|
|
3408
|
+
} catch (e) {
|
|
3409
|
+
this._logger.log(LogLevel.Error, `IRetryPolicy.nextRetryDelayInMilliseconds(${previousRetryCount}, ${elapsedMilliseconds}) threw error '${e}'.`);
|
|
3410
|
+
return null;
|
|
3411
|
+
}
|
|
3412
|
+
}
|
|
3413
|
+
_cancelCallbacksWithError(error) {
|
|
3414
|
+
const callbacks = this._callbacks;
|
|
3415
|
+
this._callbacks = {};
|
|
3416
|
+
Object.keys(callbacks).forEach((key) => {
|
|
3417
|
+
const callback = callbacks[key];
|
|
3418
|
+
try {
|
|
3419
|
+
callback(null, error);
|
|
3420
|
+
} catch (e) {
|
|
3421
|
+
this._logger.log(LogLevel.Error, `Stream 'error' callback called with '${error}' threw error: ${getErrorString(e)}`);
|
|
3422
|
+
}
|
|
3423
|
+
});
|
|
3424
|
+
}
|
|
3425
|
+
_cleanupPingTimer() {
|
|
3426
|
+
if (this._pingServerHandle) {
|
|
3427
|
+
clearTimeout(this._pingServerHandle);
|
|
3428
|
+
this._pingServerHandle = void 0;
|
|
3429
|
+
}
|
|
3430
|
+
}
|
|
3431
|
+
_cleanupTimeout() {
|
|
3432
|
+
if (this._timeoutHandle) {
|
|
3433
|
+
clearTimeout(this._timeoutHandle);
|
|
3434
|
+
}
|
|
3435
|
+
}
|
|
3436
|
+
_createInvocation(methodName, args, nonblocking, streamIds) {
|
|
3437
|
+
if (nonblocking) {
|
|
3438
|
+
if (streamIds.length !== 0) {
|
|
3439
|
+
return {
|
|
3440
|
+
arguments: args,
|
|
3441
|
+
streamIds,
|
|
3442
|
+
target: methodName,
|
|
3443
|
+
type: MessageType.Invocation
|
|
3444
|
+
};
|
|
3445
|
+
} else {
|
|
3446
|
+
return {
|
|
3447
|
+
arguments: args,
|
|
3448
|
+
target: methodName,
|
|
3449
|
+
type: MessageType.Invocation
|
|
3450
|
+
};
|
|
3451
|
+
}
|
|
3452
|
+
} else {
|
|
3453
|
+
const invocationId = this._invocationId;
|
|
3454
|
+
this._invocationId++;
|
|
3455
|
+
if (streamIds.length !== 0) {
|
|
3456
|
+
return {
|
|
3457
|
+
arguments: args,
|
|
3458
|
+
invocationId: invocationId.toString(),
|
|
3459
|
+
streamIds,
|
|
3460
|
+
target: methodName,
|
|
3461
|
+
type: MessageType.Invocation
|
|
3462
|
+
};
|
|
3463
|
+
} else {
|
|
3464
|
+
return {
|
|
3465
|
+
arguments: args,
|
|
3466
|
+
invocationId: invocationId.toString(),
|
|
3467
|
+
target: methodName,
|
|
3468
|
+
type: MessageType.Invocation
|
|
3469
|
+
};
|
|
3470
|
+
}
|
|
3471
|
+
}
|
|
3472
|
+
}
|
|
3473
|
+
_launchStreams(streams, promiseQueue) {
|
|
3474
|
+
if (streams.length === 0) {
|
|
3475
|
+
return;
|
|
3476
|
+
}
|
|
3477
|
+
if (!promiseQueue) {
|
|
3478
|
+
promiseQueue = Promise.resolve();
|
|
3479
|
+
}
|
|
3480
|
+
for (const streamId in streams) {
|
|
3481
|
+
streams[streamId].subscribe({
|
|
3482
|
+
complete: () => {
|
|
3483
|
+
promiseQueue = promiseQueue.then(() => this._sendWithProtocol(this._createCompletionMessage(streamId)));
|
|
3484
|
+
},
|
|
3485
|
+
error: (err) => {
|
|
3486
|
+
let message;
|
|
3487
|
+
if (err instanceof Error) {
|
|
3488
|
+
message = err.message;
|
|
3489
|
+
} else if (err && err.toString) {
|
|
3490
|
+
message = err.toString();
|
|
3491
|
+
} else {
|
|
3492
|
+
message = "Unknown error";
|
|
3493
|
+
}
|
|
3494
|
+
promiseQueue = promiseQueue.then(() => this._sendWithProtocol(this._createCompletionMessage(streamId, message)));
|
|
3495
|
+
},
|
|
3496
|
+
next: (item) => {
|
|
3497
|
+
promiseQueue = promiseQueue.then(() => this._sendWithProtocol(this._createStreamItemMessage(streamId, item)));
|
|
3498
|
+
}
|
|
3499
|
+
});
|
|
3500
|
+
}
|
|
3501
|
+
}
|
|
3502
|
+
_replaceStreamingParams(args) {
|
|
3503
|
+
const streams = [];
|
|
3504
|
+
const streamIds = [];
|
|
3505
|
+
for (let i = 0; i < args.length; i++) {
|
|
3506
|
+
const argument = args[i];
|
|
3507
|
+
if (this._isObservable(argument)) {
|
|
3508
|
+
const streamId = this._invocationId;
|
|
3509
|
+
this._invocationId++;
|
|
3510
|
+
streams[streamId] = argument;
|
|
3511
|
+
streamIds.push(streamId.toString());
|
|
3512
|
+
args.splice(i, 1);
|
|
3513
|
+
}
|
|
3514
|
+
}
|
|
3515
|
+
return [streams, streamIds];
|
|
3516
|
+
}
|
|
3517
|
+
_isObservable(arg) {
|
|
3518
|
+
return arg && arg.subscribe && typeof arg.subscribe === "function";
|
|
3519
|
+
}
|
|
3520
|
+
_createStreamInvocation(methodName, args, streamIds) {
|
|
3521
|
+
const invocationId = this._invocationId;
|
|
3522
|
+
this._invocationId++;
|
|
3523
|
+
if (streamIds.length !== 0) {
|
|
3524
|
+
return {
|
|
3525
|
+
arguments: args,
|
|
3526
|
+
invocationId: invocationId.toString(),
|
|
3527
|
+
streamIds,
|
|
3528
|
+
target: methodName,
|
|
3529
|
+
type: MessageType.StreamInvocation
|
|
3530
|
+
};
|
|
3531
|
+
} else {
|
|
3532
|
+
return {
|
|
3533
|
+
arguments: args,
|
|
3534
|
+
invocationId: invocationId.toString(),
|
|
3535
|
+
target: methodName,
|
|
3536
|
+
type: MessageType.StreamInvocation
|
|
3537
|
+
};
|
|
3538
|
+
}
|
|
3539
|
+
}
|
|
3540
|
+
_createCancelInvocation(id) {
|
|
3541
|
+
return {
|
|
3542
|
+
invocationId: id,
|
|
3543
|
+
type: MessageType.CancelInvocation
|
|
3544
|
+
};
|
|
3545
|
+
}
|
|
3546
|
+
_createStreamItemMessage(id, item) {
|
|
3547
|
+
return {
|
|
3548
|
+
invocationId: id,
|
|
3549
|
+
item,
|
|
3550
|
+
type: MessageType.StreamItem
|
|
3551
|
+
};
|
|
3552
|
+
}
|
|
3553
|
+
_createCompletionMessage(id, error, result) {
|
|
3554
|
+
if (error) {
|
|
3555
|
+
return {
|
|
3556
|
+
error,
|
|
3557
|
+
invocationId: id,
|
|
3558
|
+
type: MessageType.Completion
|
|
3559
|
+
};
|
|
3560
|
+
}
|
|
3561
|
+
return {
|
|
3562
|
+
invocationId: id,
|
|
3563
|
+
result,
|
|
3564
|
+
type: MessageType.Completion
|
|
3565
|
+
};
|
|
3566
|
+
}
|
|
3567
|
+
_createCloseMessage() {
|
|
3568
|
+
return { type: MessageType.Close };
|
|
3569
|
+
}
|
|
3570
|
+
};
|
|
3571
|
+
|
|
3572
|
+
// node_modules/@microsoft/signalr/dist/esm/DefaultReconnectPolicy.js
|
|
3573
|
+
var DEFAULT_RETRY_DELAYS_IN_MILLISECONDS = [0, 2e3, 1e4, 3e4, null];
|
|
3574
|
+
var DefaultReconnectPolicy = class {
|
|
3575
|
+
constructor(retryDelays) {
|
|
3576
|
+
this._retryDelays = retryDelays !== void 0 ? [...retryDelays, null] : DEFAULT_RETRY_DELAYS_IN_MILLISECONDS;
|
|
3577
|
+
}
|
|
3578
|
+
nextRetryDelayInMilliseconds(retryContext) {
|
|
3579
|
+
return this._retryDelays[retryContext.previousRetryCount];
|
|
3580
|
+
}
|
|
3581
|
+
};
|
|
3582
|
+
|
|
3583
|
+
// node_modules/@microsoft/signalr/dist/esm/HeaderNames.js
|
|
3584
|
+
var HeaderNames = class {
|
|
3585
|
+
};
|
|
3586
|
+
HeaderNames.Authorization = "Authorization";
|
|
3587
|
+
HeaderNames.Cookie = "Cookie";
|
|
3588
|
+
|
|
3589
|
+
// node_modules/@microsoft/signalr/dist/esm/AccessTokenHttpClient.js
|
|
3590
|
+
var AccessTokenHttpClient = class extends HttpClient {
|
|
3591
|
+
constructor(innerClient, accessTokenFactory) {
|
|
3592
|
+
super();
|
|
3593
|
+
this._innerClient = innerClient;
|
|
3594
|
+
this._accessTokenFactory = accessTokenFactory;
|
|
3595
|
+
}
|
|
3596
|
+
async send(request) {
|
|
3597
|
+
let allowRetry = true;
|
|
3598
|
+
if (this._accessTokenFactory && (!this._accessToken || request.url && request.url.indexOf("/negotiate?") > 0)) {
|
|
3599
|
+
allowRetry = false;
|
|
3600
|
+
this._accessToken = await this._accessTokenFactory();
|
|
3601
|
+
}
|
|
3602
|
+
this._setAuthorizationHeader(request);
|
|
3603
|
+
const response = await this._innerClient.send(request);
|
|
3604
|
+
if (allowRetry && response.statusCode === 401 && this._accessTokenFactory) {
|
|
3605
|
+
this._accessToken = await this._accessTokenFactory();
|
|
3606
|
+
this._setAuthorizationHeader(request);
|
|
3607
|
+
return await this._innerClient.send(request);
|
|
3608
|
+
}
|
|
3609
|
+
return response;
|
|
3610
|
+
}
|
|
3611
|
+
_setAuthorizationHeader(request) {
|
|
3612
|
+
if (!request.headers) {
|
|
3613
|
+
request.headers = {};
|
|
3614
|
+
}
|
|
3615
|
+
if (this._accessToken) {
|
|
3616
|
+
request.headers[HeaderNames.Authorization] = `Bearer ${this._accessToken}`;
|
|
3617
|
+
} else if (this._accessTokenFactory) {
|
|
3618
|
+
if (request.headers[HeaderNames.Authorization]) {
|
|
3619
|
+
delete request.headers[HeaderNames.Authorization];
|
|
3620
|
+
}
|
|
3621
|
+
}
|
|
3622
|
+
}
|
|
3623
|
+
getCookieString(url) {
|
|
3624
|
+
return this._innerClient.getCookieString(url);
|
|
3625
|
+
}
|
|
3626
|
+
};
|
|
3627
|
+
|
|
3628
|
+
// node_modules/@microsoft/signalr/dist/esm/ITransport.js
|
|
3629
|
+
var HttpTransportType;
|
|
3630
|
+
(function(HttpTransportType2) {
|
|
3631
|
+
HttpTransportType2[HttpTransportType2["None"] = 0] = "None";
|
|
3632
|
+
HttpTransportType2[HttpTransportType2["WebSockets"] = 1] = "WebSockets";
|
|
3633
|
+
HttpTransportType2[HttpTransportType2["ServerSentEvents"] = 2] = "ServerSentEvents";
|
|
3634
|
+
HttpTransportType2[HttpTransportType2["LongPolling"] = 4] = "LongPolling";
|
|
3635
|
+
})(HttpTransportType || (HttpTransportType = {}));
|
|
3636
|
+
var TransferFormat;
|
|
3637
|
+
(function(TransferFormat2) {
|
|
3638
|
+
TransferFormat2[TransferFormat2["Text"] = 1] = "Text";
|
|
3639
|
+
TransferFormat2[TransferFormat2["Binary"] = 2] = "Binary";
|
|
3640
|
+
})(TransferFormat || (TransferFormat = {}));
|
|
3641
|
+
|
|
3642
|
+
// node_modules/@microsoft/signalr/dist/esm/AbortController.js
|
|
3643
|
+
var AbortController2 = class {
|
|
3644
|
+
constructor() {
|
|
3645
|
+
this._isAborted = false;
|
|
3646
|
+
this.onabort = null;
|
|
3647
|
+
}
|
|
3648
|
+
abort() {
|
|
3649
|
+
if (!this._isAborted) {
|
|
3650
|
+
this._isAborted = true;
|
|
3651
|
+
if (this.onabort) {
|
|
3652
|
+
this.onabort();
|
|
3653
|
+
}
|
|
3654
|
+
}
|
|
3655
|
+
}
|
|
3656
|
+
get signal() {
|
|
3657
|
+
return this;
|
|
3658
|
+
}
|
|
3659
|
+
get aborted() {
|
|
3660
|
+
return this._isAborted;
|
|
3661
|
+
}
|
|
3662
|
+
};
|
|
3663
|
+
|
|
3664
|
+
// node_modules/@microsoft/signalr/dist/esm/LongPollingTransport.js
|
|
3665
|
+
var LongPollingTransport = class {
|
|
3666
|
+
// This is an internal type, not exported from 'index' so this is really just internal.
|
|
3667
|
+
get pollAborted() {
|
|
3668
|
+
return this._pollAbort.aborted;
|
|
3669
|
+
}
|
|
3670
|
+
constructor(httpClient, logger, options) {
|
|
3671
|
+
this._httpClient = httpClient;
|
|
3672
|
+
this._logger = logger;
|
|
3673
|
+
this._pollAbort = new AbortController2();
|
|
3674
|
+
this._options = options;
|
|
3675
|
+
this._running = false;
|
|
3676
|
+
this.onreceive = null;
|
|
3677
|
+
this.onclose = null;
|
|
3678
|
+
}
|
|
3679
|
+
async connect(url, transferFormat) {
|
|
3680
|
+
Arg.isRequired(url, "url");
|
|
3681
|
+
Arg.isRequired(transferFormat, "transferFormat");
|
|
3682
|
+
Arg.isIn(transferFormat, TransferFormat, "transferFormat");
|
|
3683
|
+
this._url = url;
|
|
3684
|
+
this._logger.log(LogLevel.Trace, "(LongPolling transport) Connecting.");
|
|
3685
|
+
if (transferFormat === TransferFormat.Binary && (typeof XMLHttpRequest !== "undefined" && typeof new XMLHttpRequest().responseType !== "string")) {
|
|
3686
|
+
throw new Error("Binary protocols over XmlHttpRequest not implementing advanced features are not supported.");
|
|
3687
|
+
}
|
|
3688
|
+
const [name, value] = getUserAgentHeader();
|
|
3689
|
+
const headers = { [name]: value, ...this._options.headers };
|
|
3690
|
+
const pollOptions = {
|
|
3691
|
+
abortSignal: this._pollAbort.signal,
|
|
3692
|
+
headers,
|
|
3693
|
+
timeout: 1e5,
|
|
3694
|
+
withCredentials: this._options.withCredentials
|
|
3695
|
+
};
|
|
3696
|
+
if (transferFormat === TransferFormat.Binary) {
|
|
3697
|
+
pollOptions.responseType = "arraybuffer";
|
|
3698
|
+
}
|
|
3699
|
+
const pollUrl = `${url}&_=${Date.now()}`;
|
|
3700
|
+
this._logger.log(LogLevel.Trace, `(LongPolling transport) polling: ${pollUrl}.`);
|
|
3701
|
+
const response = await this._httpClient.get(pollUrl, pollOptions);
|
|
3702
|
+
if (response.statusCode !== 200) {
|
|
3703
|
+
this._logger.log(LogLevel.Error, `(LongPolling transport) Unexpected response code: ${response.statusCode}.`);
|
|
3704
|
+
this._closeError = new HttpError(response.statusText || "", response.statusCode);
|
|
3705
|
+
this._running = false;
|
|
3706
|
+
} else {
|
|
3707
|
+
this._running = true;
|
|
3708
|
+
}
|
|
3709
|
+
this._receiving = this._poll(this._url, pollOptions);
|
|
3710
|
+
}
|
|
3711
|
+
async _poll(url, pollOptions) {
|
|
3712
|
+
try {
|
|
3713
|
+
while (this._running) {
|
|
3714
|
+
try {
|
|
3715
|
+
const pollUrl = `${url}&_=${Date.now()}`;
|
|
3716
|
+
this._logger.log(LogLevel.Trace, `(LongPolling transport) polling: ${pollUrl}.`);
|
|
3717
|
+
const response = await this._httpClient.get(pollUrl, pollOptions);
|
|
3718
|
+
if (response.statusCode === 204) {
|
|
3719
|
+
this._logger.log(LogLevel.Information, "(LongPolling transport) Poll terminated by server.");
|
|
3720
|
+
this._running = false;
|
|
3721
|
+
} else if (response.statusCode !== 200) {
|
|
3722
|
+
this._logger.log(LogLevel.Error, `(LongPolling transport) Unexpected response code: ${response.statusCode}.`);
|
|
3723
|
+
this._closeError = new HttpError(response.statusText || "", response.statusCode);
|
|
3724
|
+
this._running = false;
|
|
3725
|
+
} else {
|
|
3726
|
+
if (response.content) {
|
|
3727
|
+
this._logger.log(LogLevel.Trace, `(LongPolling transport) data received. ${getDataDetail(response.content, this._options.logMessageContent)}.`);
|
|
3728
|
+
if (this.onreceive) {
|
|
3729
|
+
this.onreceive(response.content);
|
|
3730
|
+
}
|
|
3731
|
+
} else {
|
|
3732
|
+
this._logger.log(LogLevel.Trace, "(LongPolling transport) Poll timed out, reissuing.");
|
|
3733
|
+
}
|
|
3734
|
+
}
|
|
3735
|
+
} catch (e) {
|
|
3736
|
+
if (!this._running) {
|
|
3737
|
+
this._logger.log(LogLevel.Trace, `(LongPolling transport) Poll errored after shutdown: ${e.message}`);
|
|
3738
|
+
} else {
|
|
3739
|
+
if (e instanceof TimeoutError) {
|
|
3740
|
+
this._logger.log(LogLevel.Trace, "(LongPolling transport) Poll timed out, reissuing.");
|
|
3741
|
+
} else {
|
|
3742
|
+
this._closeError = e;
|
|
3743
|
+
this._running = false;
|
|
3744
|
+
}
|
|
3745
|
+
}
|
|
3746
|
+
}
|
|
3747
|
+
}
|
|
3748
|
+
} finally {
|
|
3749
|
+
this._logger.log(LogLevel.Trace, "(LongPolling transport) Polling complete.");
|
|
3750
|
+
if (!this.pollAborted) {
|
|
3751
|
+
this._raiseOnClose();
|
|
3752
|
+
}
|
|
3753
|
+
}
|
|
3754
|
+
}
|
|
3755
|
+
async send(data) {
|
|
3756
|
+
if (!this._running) {
|
|
3757
|
+
return Promise.reject(new Error("Cannot send until the transport is connected"));
|
|
3758
|
+
}
|
|
3759
|
+
return sendMessage(this._logger, "LongPolling", this._httpClient, this._url, data, this._options);
|
|
3760
|
+
}
|
|
3761
|
+
async stop() {
|
|
3762
|
+
this._logger.log(LogLevel.Trace, "(LongPolling transport) Stopping polling.");
|
|
3763
|
+
this._running = false;
|
|
3764
|
+
this._pollAbort.abort();
|
|
3765
|
+
try {
|
|
3766
|
+
await this._receiving;
|
|
3767
|
+
this._logger.log(LogLevel.Trace, `(LongPolling transport) sending DELETE request to ${this._url}.`);
|
|
3768
|
+
const headers = {};
|
|
3769
|
+
const [name, value] = getUserAgentHeader();
|
|
3770
|
+
headers[name] = value;
|
|
3771
|
+
const deleteOptions = {
|
|
3772
|
+
headers: { ...headers, ...this._options.headers },
|
|
3773
|
+
timeout: this._options.timeout,
|
|
3774
|
+
withCredentials: this._options.withCredentials
|
|
3775
|
+
};
|
|
3776
|
+
let error;
|
|
3777
|
+
try {
|
|
3778
|
+
await this._httpClient.delete(this._url, deleteOptions);
|
|
3779
|
+
} catch (err) {
|
|
3780
|
+
error = err;
|
|
3781
|
+
}
|
|
3782
|
+
if (error) {
|
|
3783
|
+
if (error instanceof HttpError) {
|
|
3784
|
+
if (error.statusCode === 404) {
|
|
3785
|
+
this._logger.log(LogLevel.Trace, "(LongPolling transport) A 404 response was returned from sending a DELETE request.");
|
|
3786
|
+
} else {
|
|
3787
|
+
this._logger.log(LogLevel.Trace, `(LongPolling transport) Error sending a DELETE request: ${error}`);
|
|
3788
|
+
}
|
|
3789
|
+
}
|
|
3790
|
+
} else {
|
|
3791
|
+
this._logger.log(LogLevel.Trace, "(LongPolling transport) DELETE request accepted.");
|
|
3792
|
+
}
|
|
3793
|
+
} finally {
|
|
3794
|
+
this._logger.log(LogLevel.Trace, "(LongPolling transport) Stop finished.");
|
|
3795
|
+
this._raiseOnClose();
|
|
3796
|
+
}
|
|
3797
|
+
}
|
|
3798
|
+
_raiseOnClose() {
|
|
3799
|
+
if (this.onclose) {
|
|
3800
|
+
let logMessage = "(LongPolling transport) Firing onclose event.";
|
|
3801
|
+
if (this._closeError) {
|
|
3802
|
+
logMessage += " Error: " + this._closeError;
|
|
3803
|
+
}
|
|
3804
|
+
this._logger.log(LogLevel.Trace, logMessage);
|
|
3805
|
+
this.onclose(this._closeError);
|
|
3806
|
+
}
|
|
3807
|
+
}
|
|
3808
|
+
};
|
|
3809
|
+
|
|
3810
|
+
// node_modules/@microsoft/signalr/dist/esm/ServerSentEventsTransport.js
|
|
3811
|
+
var ServerSentEventsTransport = class {
|
|
3812
|
+
constructor(httpClient, accessToken, logger, options) {
|
|
3813
|
+
this._httpClient = httpClient;
|
|
3814
|
+
this._accessToken = accessToken;
|
|
3815
|
+
this._logger = logger;
|
|
3816
|
+
this._options = options;
|
|
3817
|
+
this.onreceive = null;
|
|
3818
|
+
this.onclose = null;
|
|
3819
|
+
}
|
|
3820
|
+
async connect(url, transferFormat) {
|
|
3821
|
+
Arg.isRequired(url, "url");
|
|
3822
|
+
Arg.isRequired(transferFormat, "transferFormat");
|
|
3823
|
+
Arg.isIn(transferFormat, TransferFormat, "transferFormat");
|
|
3824
|
+
this._logger.log(LogLevel.Trace, "(SSE transport) Connecting.");
|
|
3825
|
+
this._url = url;
|
|
3826
|
+
if (this._accessToken) {
|
|
3827
|
+
url += (url.indexOf("?") < 0 ? "?" : "&") + `access_token=${encodeURIComponent(this._accessToken)}`;
|
|
3828
|
+
}
|
|
3829
|
+
return new Promise((resolve, reject) => {
|
|
3830
|
+
let opened = false;
|
|
3831
|
+
if (transferFormat !== TransferFormat.Text) {
|
|
3832
|
+
reject(new Error("The Server-Sent Events transport only supports the 'Text' transfer format"));
|
|
3833
|
+
return;
|
|
3834
|
+
}
|
|
3835
|
+
let eventSource;
|
|
3836
|
+
if (Platform.isBrowser || Platform.isWebWorker) {
|
|
3837
|
+
eventSource = new this._options.EventSource(url, { withCredentials: this._options.withCredentials });
|
|
3838
|
+
} else {
|
|
3839
|
+
const cookies = this._httpClient.getCookieString(url);
|
|
3840
|
+
const headers = {};
|
|
3841
|
+
headers.Cookie = cookies;
|
|
3842
|
+
const [name, value] = getUserAgentHeader();
|
|
3843
|
+
headers[name] = value;
|
|
3844
|
+
eventSource = new this._options.EventSource(url, { withCredentials: this._options.withCredentials, headers: { ...headers, ...this._options.headers } });
|
|
3845
|
+
}
|
|
3846
|
+
try {
|
|
3847
|
+
eventSource.onmessage = (e) => {
|
|
3848
|
+
if (this.onreceive) {
|
|
3849
|
+
try {
|
|
3850
|
+
this._logger.log(LogLevel.Trace, `(SSE transport) data received. ${getDataDetail(e.data, this._options.logMessageContent)}.`);
|
|
3851
|
+
this.onreceive(e.data);
|
|
3852
|
+
} catch (error) {
|
|
3853
|
+
this._close(error);
|
|
3854
|
+
return;
|
|
3855
|
+
}
|
|
3856
|
+
}
|
|
3857
|
+
};
|
|
3858
|
+
eventSource.onerror = (e) => {
|
|
3859
|
+
if (opened) {
|
|
3860
|
+
this._close();
|
|
3861
|
+
} else {
|
|
3862
|
+
reject(new Error("EventSource failed to connect. The connection could not be found on the server, either the connection ID is not present on the server, or a proxy is refusing/buffering the connection. If you have multiple servers check that sticky sessions are enabled."));
|
|
3863
|
+
}
|
|
3864
|
+
};
|
|
3865
|
+
eventSource.onopen = () => {
|
|
3866
|
+
this._logger.log(LogLevel.Information, `SSE connected to ${this._url}`);
|
|
3867
|
+
this._eventSource = eventSource;
|
|
3868
|
+
opened = true;
|
|
3869
|
+
resolve();
|
|
3870
|
+
};
|
|
3871
|
+
} catch (e) {
|
|
3872
|
+
reject(e);
|
|
3873
|
+
return;
|
|
3874
|
+
}
|
|
3875
|
+
});
|
|
3876
|
+
}
|
|
3877
|
+
async send(data) {
|
|
3878
|
+
if (!this._eventSource) {
|
|
3879
|
+
return Promise.reject(new Error("Cannot send until the transport is connected"));
|
|
3880
|
+
}
|
|
3881
|
+
return sendMessage(this._logger, "SSE", this._httpClient, this._url, data, this._options);
|
|
3882
|
+
}
|
|
3883
|
+
stop() {
|
|
3884
|
+
this._close();
|
|
3885
|
+
return Promise.resolve();
|
|
3886
|
+
}
|
|
3887
|
+
_close(e) {
|
|
3888
|
+
if (this._eventSource) {
|
|
3889
|
+
this._eventSource.close();
|
|
3890
|
+
this._eventSource = void 0;
|
|
3891
|
+
if (this.onclose) {
|
|
3892
|
+
this.onclose(e);
|
|
3893
|
+
}
|
|
3894
|
+
}
|
|
3895
|
+
}
|
|
3896
|
+
};
|
|
3897
|
+
|
|
3898
|
+
// node_modules/@microsoft/signalr/dist/esm/WebSocketTransport.js
|
|
3899
|
+
var WebSocketTransport = class {
|
|
3900
|
+
constructor(httpClient, accessTokenFactory, logger, logMessageContent, webSocketConstructor, headers) {
|
|
3901
|
+
this._logger = logger;
|
|
3902
|
+
this._accessTokenFactory = accessTokenFactory;
|
|
3903
|
+
this._logMessageContent = logMessageContent;
|
|
3904
|
+
this._webSocketConstructor = webSocketConstructor;
|
|
3905
|
+
this._httpClient = httpClient;
|
|
3906
|
+
this.onreceive = null;
|
|
3907
|
+
this.onclose = null;
|
|
3908
|
+
this._headers = headers;
|
|
3909
|
+
}
|
|
3910
|
+
async connect(url, transferFormat) {
|
|
3911
|
+
Arg.isRequired(url, "url");
|
|
3912
|
+
Arg.isRequired(transferFormat, "transferFormat");
|
|
3913
|
+
Arg.isIn(transferFormat, TransferFormat, "transferFormat");
|
|
3914
|
+
this._logger.log(LogLevel.Trace, "(WebSockets transport) Connecting.");
|
|
3915
|
+
let token;
|
|
3916
|
+
if (this._accessTokenFactory) {
|
|
3917
|
+
token = await this._accessTokenFactory();
|
|
3918
|
+
}
|
|
3919
|
+
return new Promise((resolve, reject) => {
|
|
3920
|
+
url = url.replace(/^http/, "ws");
|
|
3921
|
+
let webSocket;
|
|
3922
|
+
const cookies = this._httpClient.getCookieString(url);
|
|
3923
|
+
let opened = false;
|
|
3924
|
+
if (Platform.isNode || Platform.isReactNative) {
|
|
3925
|
+
const headers = {};
|
|
3926
|
+
const [name, value] = getUserAgentHeader();
|
|
3927
|
+
headers[name] = value;
|
|
3928
|
+
if (token) {
|
|
3929
|
+
headers[HeaderNames.Authorization] = `Bearer ${token}`;
|
|
3930
|
+
}
|
|
3931
|
+
if (cookies) {
|
|
3932
|
+
headers[HeaderNames.Cookie] = cookies;
|
|
3933
|
+
}
|
|
3934
|
+
webSocket = new this._webSocketConstructor(url, void 0, {
|
|
3935
|
+
headers: { ...headers, ...this._headers }
|
|
3936
|
+
});
|
|
3937
|
+
} else {
|
|
3938
|
+
if (token) {
|
|
3939
|
+
url += (url.indexOf("?") < 0 ? "?" : "&") + `access_token=${encodeURIComponent(token)}`;
|
|
3940
|
+
}
|
|
3941
|
+
}
|
|
3942
|
+
if (!webSocket) {
|
|
3943
|
+
webSocket = new this._webSocketConstructor(url);
|
|
3944
|
+
}
|
|
3945
|
+
if (transferFormat === TransferFormat.Binary) {
|
|
3946
|
+
webSocket.binaryType = "arraybuffer";
|
|
3947
|
+
}
|
|
3948
|
+
webSocket.onopen = (_event) => {
|
|
3949
|
+
this._logger.log(LogLevel.Information, `WebSocket connected to ${url}.`);
|
|
3950
|
+
this._webSocket = webSocket;
|
|
3951
|
+
opened = true;
|
|
3952
|
+
resolve();
|
|
3953
|
+
};
|
|
3954
|
+
webSocket.onerror = (event) => {
|
|
3955
|
+
let error = null;
|
|
3956
|
+
if (typeof ErrorEvent !== "undefined" && event instanceof ErrorEvent) {
|
|
3957
|
+
error = event.error;
|
|
3958
|
+
} else {
|
|
3959
|
+
error = "There was an error with the transport";
|
|
3960
|
+
}
|
|
3961
|
+
this._logger.log(LogLevel.Information, `(WebSockets transport) ${error}.`);
|
|
3962
|
+
};
|
|
3963
|
+
webSocket.onmessage = (message) => {
|
|
3964
|
+
this._logger.log(LogLevel.Trace, `(WebSockets transport) data received. ${getDataDetail(message.data, this._logMessageContent)}.`);
|
|
3965
|
+
if (this.onreceive) {
|
|
3966
|
+
try {
|
|
3967
|
+
this.onreceive(message.data);
|
|
3968
|
+
} catch (error) {
|
|
3969
|
+
this._close(error);
|
|
3970
|
+
return;
|
|
3971
|
+
}
|
|
3972
|
+
}
|
|
3973
|
+
};
|
|
3974
|
+
webSocket.onclose = (event) => {
|
|
3975
|
+
if (opened) {
|
|
3976
|
+
this._close(event);
|
|
3977
|
+
} else {
|
|
3978
|
+
let error = null;
|
|
3979
|
+
if (typeof ErrorEvent !== "undefined" && event instanceof ErrorEvent) {
|
|
3980
|
+
error = event.error;
|
|
3981
|
+
} else {
|
|
3982
|
+
error = "WebSocket failed to connect. The connection could not be found on the server, either the endpoint may not be a SignalR endpoint, the connection ID is not present on the server, or there is a proxy blocking WebSockets. If you have multiple servers check that sticky sessions are enabled.";
|
|
3983
|
+
}
|
|
3984
|
+
reject(new Error(error));
|
|
3985
|
+
}
|
|
3986
|
+
};
|
|
3987
|
+
});
|
|
3988
|
+
}
|
|
3989
|
+
send(data) {
|
|
3990
|
+
if (this._webSocket && this._webSocket.readyState === this._webSocketConstructor.OPEN) {
|
|
3991
|
+
this._logger.log(LogLevel.Trace, `(WebSockets transport) sending data. ${getDataDetail(data, this._logMessageContent)}.`);
|
|
3992
|
+
this._webSocket.send(data);
|
|
3993
|
+
return Promise.resolve();
|
|
3994
|
+
}
|
|
3995
|
+
return Promise.reject("WebSocket is not in the OPEN state");
|
|
3996
|
+
}
|
|
3997
|
+
stop() {
|
|
3998
|
+
if (this._webSocket) {
|
|
3999
|
+
this._close(void 0);
|
|
4000
|
+
}
|
|
4001
|
+
return Promise.resolve();
|
|
4002
|
+
}
|
|
4003
|
+
_close(event) {
|
|
4004
|
+
if (this._webSocket) {
|
|
4005
|
+
this._webSocket.onclose = () => {
|
|
4006
|
+
};
|
|
4007
|
+
this._webSocket.onmessage = () => {
|
|
4008
|
+
};
|
|
4009
|
+
this._webSocket.onerror = () => {
|
|
4010
|
+
};
|
|
4011
|
+
this._webSocket.close();
|
|
4012
|
+
this._webSocket = void 0;
|
|
4013
|
+
}
|
|
4014
|
+
this._logger.log(LogLevel.Trace, "(WebSockets transport) socket closed.");
|
|
4015
|
+
if (this.onclose) {
|
|
4016
|
+
if (this._isCloseEvent(event) && (event.wasClean === false || event.code !== 1e3)) {
|
|
4017
|
+
this.onclose(new Error(`WebSocket closed with status code: ${event.code} (${event.reason || "no reason given"}).`));
|
|
4018
|
+
} else if (event instanceof Error) {
|
|
4019
|
+
this.onclose(event);
|
|
4020
|
+
} else {
|
|
4021
|
+
this.onclose();
|
|
4022
|
+
}
|
|
4023
|
+
}
|
|
4024
|
+
}
|
|
4025
|
+
_isCloseEvent(event) {
|
|
4026
|
+
return event && typeof event.wasClean === "boolean" && typeof event.code === "number";
|
|
4027
|
+
}
|
|
4028
|
+
};
|
|
4029
|
+
|
|
4030
|
+
// node_modules/@microsoft/signalr/dist/esm/HttpConnection.js
|
|
4031
|
+
var MAX_REDIRECTS = 100;
|
|
4032
|
+
var HttpConnection = class {
|
|
4033
|
+
constructor(url, options = {}) {
|
|
4034
|
+
this._stopPromiseResolver = () => {
|
|
4035
|
+
};
|
|
4036
|
+
this.features = {};
|
|
4037
|
+
this._negotiateVersion = 1;
|
|
4038
|
+
Arg.isRequired(url, "url");
|
|
4039
|
+
this._logger = createLogger(options.logger);
|
|
4040
|
+
this.baseUrl = this._resolveUrl(url);
|
|
4041
|
+
options = options || {};
|
|
4042
|
+
options.logMessageContent = options.logMessageContent === void 0 ? false : options.logMessageContent;
|
|
4043
|
+
if (typeof options.withCredentials === "boolean" || options.withCredentials === void 0) {
|
|
4044
|
+
options.withCredentials = options.withCredentials === void 0 ? true : options.withCredentials;
|
|
4045
|
+
} else {
|
|
4046
|
+
throw new Error("withCredentials option was not a 'boolean' or 'undefined' value");
|
|
4047
|
+
}
|
|
4048
|
+
options.timeout = options.timeout === void 0 ? 100 * 1e3 : options.timeout;
|
|
4049
|
+
let webSocketModule = null;
|
|
4050
|
+
let eventSourceModule = null;
|
|
4051
|
+
if (Platform.isNode && typeof __require !== "undefined") {
|
|
4052
|
+
const requireFunc = typeof __webpack_require__ === "function" ? __non_webpack_require__ : __require;
|
|
4053
|
+
webSocketModule = requireFunc("ws");
|
|
4054
|
+
eventSourceModule = requireFunc("eventsource");
|
|
4055
|
+
}
|
|
4056
|
+
if (!Platform.isNode && typeof WebSocket !== "undefined" && !options.WebSocket) {
|
|
4057
|
+
options.WebSocket = WebSocket;
|
|
4058
|
+
} else if (Platform.isNode && !options.WebSocket) {
|
|
4059
|
+
if (webSocketModule) {
|
|
4060
|
+
options.WebSocket = webSocketModule;
|
|
4061
|
+
}
|
|
4062
|
+
}
|
|
4063
|
+
if (!Platform.isNode && typeof EventSource !== "undefined" && !options.EventSource) {
|
|
4064
|
+
options.EventSource = EventSource;
|
|
4065
|
+
} else if (Platform.isNode && !options.EventSource) {
|
|
4066
|
+
if (typeof eventSourceModule !== "undefined") {
|
|
4067
|
+
options.EventSource = eventSourceModule;
|
|
4068
|
+
}
|
|
4069
|
+
}
|
|
4070
|
+
this._httpClient = new AccessTokenHttpClient(options.httpClient || new DefaultHttpClient(this._logger), options.accessTokenFactory);
|
|
4071
|
+
this._connectionState = "Disconnected";
|
|
4072
|
+
this._connectionStarted = false;
|
|
4073
|
+
this._options = options;
|
|
4074
|
+
this.onreceive = null;
|
|
4075
|
+
this.onclose = null;
|
|
4076
|
+
}
|
|
4077
|
+
async start(transferFormat) {
|
|
4078
|
+
transferFormat = transferFormat || TransferFormat.Binary;
|
|
4079
|
+
Arg.isIn(transferFormat, TransferFormat, "transferFormat");
|
|
4080
|
+
this._logger.log(LogLevel.Debug, `Starting connection with transfer format '${TransferFormat[transferFormat]}'.`);
|
|
4081
|
+
if (this._connectionState !== "Disconnected") {
|
|
4082
|
+
return Promise.reject(new Error("Cannot start an HttpConnection that is not in the 'Disconnected' state."));
|
|
4083
|
+
}
|
|
4084
|
+
this._connectionState = "Connecting";
|
|
4085
|
+
this._startInternalPromise = this._startInternal(transferFormat);
|
|
4086
|
+
await this._startInternalPromise;
|
|
4087
|
+
if (this._connectionState === "Disconnecting") {
|
|
4088
|
+
const message = "Failed to start the HttpConnection before stop() was called.";
|
|
4089
|
+
this._logger.log(LogLevel.Error, message);
|
|
4090
|
+
await this._stopPromise;
|
|
4091
|
+
return Promise.reject(new AbortError(message));
|
|
4092
|
+
} else if (this._connectionState !== "Connected") {
|
|
4093
|
+
const message = "HttpConnection.startInternal completed gracefully but didn't enter the connection into the connected state!";
|
|
4094
|
+
this._logger.log(LogLevel.Error, message);
|
|
4095
|
+
return Promise.reject(new AbortError(message));
|
|
4096
|
+
}
|
|
4097
|
+
this._connectionStarted = true;
|
|
4098
|
+
}
|
|
4099
|
+
send(data) {
|
|
4100
|
+
if (this._connectionState !== "Connected") {
|
|
4101
|
+
return Promise.reject(new Error("Cannot send data if the connection is not in the 'Connected' State."));
|
|
4102
|
+
}
|
|
4103
|
+
if (!this._sendQueue) {
|
|
4104
|
+
this._sendQueue = new TransportSendQueue(this.transport);
|
|
4105
|
+
}
|
|
4106
|
+
return this._sendQueue.send(data);
|
|
4107
|
+
}
|
|
4108
|
+
async stop(error) {
|
|
4109
|
+
if (this._connectionState === "Disconnected") {
|
|
4110
|
+
this._logger.log(LogLevel.Debug, `Call to HttpConnection.stop(${error}) ignored because the connection is already in the disconnected state.`);
|
|
4111
|
+
return Promise.resolve();
|
|
4112
|
+
}
|
|
4113
|
+
if (this._connectionState === "Disconnecting") {
|
|
4114
|
+
this._logger.log(LogLevel.Debug, `Call to HttpConnection.stop(${error}) ignored because the connection is already in the disconnecting state.`);
|
|
4115
|
+
return this._stopPromise;
|
|
4116
|
+
}
|
|
4117
|
+
this._connectionState = "Disconnecting";
|
|
4118
|
+
this._stopPromise = new Promise((resolve) => {
|
|
4119
|
+
this._stopPromiseResolver = resolve;
|
|
4120
|
+
});
|
|
4121
|
+
await this._stopInternal(error);
|
|
4122
|
+
await this._stopPromise;
|
|
4123
|
+
}
|
|
4124
|
+
async _stopInternal(error) {
|
|
4125
|
+
this._stopError = error;
|
|
4126
|
+
try {
|
|
4127
|
+
await this._startInternalPromise;
|
|
4128
|
+
} catch (e) {
|
|
4129
|
+
}
|
|
4130
|
+
if (this.transport) {
|
|
4131
|
+
try {
|
|
4132
|
+
await this.transport.stop();
|
|
4133
|
+
} catch (e) {
|
|
4134
|
+
this._logger.log(LogLevel.Error, `HttpConnection.transport.stop() threw error '${e}'.`);
|
|
4135
|
+
this._stopConnection();
|
|
4136
|
+
}
|
|
4137
|
+
this.transport = void 0;
|
|
4138
|
+
} else {
|
|
4139
|
+
this._logger.log(LogLevel.Debug, "HttpConnection.transport is undefined in HttpConnection.stop() because start() failed.");
|
|
4140
|
+
}
|
|
4141
|
+
}
|
|
4142
|
+
async _startInternal(transferFormat) {
|
|
4143
|
+
let url = this.baseUrl;
|
|
4144
|
+
this._accessTokenFactory = this._options.accessTokenFactory;
|
|
4145
|
+
this._httpClient._accessTokenFactory = this._accessTokenFactory;
|
|
4146
|
+
try {
|
|
4147
|
+
if (this._options.skipNegotiation) {
|
|
4148
|
+
if (this._options.transport === HttpTransportType.WebSockets) {
|
|
4149
|
+
this.transport = this._constructTransport(HttpTransportType.WebSockets);
|
|
4150
|
+
await this._startTransport(url, transferFormat);
|
|
4151
|
+
} else {
|
|
4152
|
+
throw new Error("Negotiation can only be skipped when using the WebSocket transport directly.");
|
|
4153
|
+
}
|
|
4154
|
+
} else {
|
|
4155
|
+
let negotiateResponse = null;
|
|
4156
|
+
let redirects = 0;
|
|
4157
|
+
do {
|
|
4158
|
+
negotiateResponse = await this._getNegotiationResponse(url);
|
|
4159
|
+
if (this._connectionState === "Disconnecting" || this._connectionState === "Disconnected") {
|
|
4160
|
+
throw new AbortError("The connection was stopped during negotiation.");
|
|
4161
|
+
}
|
|
4162
|
+
if (negotiateResponse.error) {
|
|
4163
|
+
throw new Error(negotiateResponse.error);
|
|
4164
|
+
}
|
|
4165
|
+
if (negotiateResponse.ProtocolVersion) {
|
|
4166
|
+
throw new Error("Detected a connection attempt to an ASP.NET SignalR Server. This client only supports connecting to an ASP.NET Core SignalR Server. See https://aka.ms/signalr-core-differences for details.");
|
|
4167
|
+
}
|
|
4168
|
+
if (negotiateResponse.url) {
|
|
4169
|
+
url = negotiateResponse.url;
|
|
4170
|
+
}
|
|
4171
|
+
if (negotiateResponse.accessToken) {
|
|
4172
|
+
const accessToken = negotiateResponse.accessToken;
|
|
4173
|
+
this._accessTokenFactory = () => accessToken;
|
|
4174
|
+
this._httpClient._accessToken = accessToken;
|
|
4175
|
+
this._httpClient._accessTokenFactory = void 0;
|
|
4176
|
+
}
|
|
4177
|
+
redirects++;
|
|
4178
|
+
} while (negotiateResponse.url && redirects < MAX_REDIRECTS);
|
|
4179
|
+
if (redirects === MAX_REDIRECTS && negotiateResponse.url) {
|
|
4180
|
+
throw new Error("Negotiate redirection limit exceeded.");
|
|
4181
|
+
}
|
|
4182
|
+
await this._createTransport(url, this._options.transport, negotiateResponse, transferFormat);
|
|
4183
|
+
}
|
|
4184
|
+
if (this.transport instanceof LongPollingTransport) {
|
|
4185
|
+
this.features.inherentKeepAlive = true;
|
|
4186
|
+
}
|
|
4187
|
+
if (this._connectionState === "Connecting") {
|
|
4188
|
+
this._logger.log(LogLevel.Debug, "The HttpConnection connected successfully.");
|
|
4189
|
+
this._connectionState = "Connected";
|
|
4190
|
+
}
|
|
4191
|
+
} catch (e) {
|
|
4192
|
+
this._logger.log(LogLevel.Error, "Failed to start the connection: " + e);
|
|
4193
|
+
this._connectionState = "Disconnected";
|
|
4194
|
+
this.transport = void 0;
|
|
4195
|
+
this._stopPromiseResolver();
|
|
4196
|
+
return Promise.reject(e);
|
|
4197
|
+
}
|
|
4198
|
+
}
|
|
4199
|
+
async _getNegotiationResponse(url) {
|
|
4200
|
+
const headers = {};
|
|
4201
|
+
const [name, value] = getUserAgentHeader();
|
|
4202
|
+
headers[name] = value;
|
|
4203
|
+
const negotiateUrl = this._resolveNegotiateUrl(url);
|
|
4204
|
+
this._logger.log(LogLevel.Debug, `Sending negotiation request: ${negotiateUrl}.`);
|
|
4205
|
+
try {
|
|
4206
|
+
const response = await this._httpClient.post(negotiateUrl, {
|
|
4207
|
+
content: "",
|
|
4208
|
+
headers: { ...headers, ...this._options.headers },
|
|
4209
|
+
timeout: this._options.timeout,
|
|
4210
|
+
withCredentials: this._options.withCredentials
|
|
4211
|
+
});
|
|
4212
|
+
if (response.statusCode !== 200) {
|
|
4213
|
+
return Promise.reject(new Error(`Unexpected status code returned from negotiate '${response.statusCode}'`));
|
|
4214
|
+
}
|
|
4215
|
+
const negotiateResponse = JSON.parse(response.content);
|
|
4216
|
+
if (!negotiateResponse.negotiateVersion || negotiateResponse.negotiateVersion < 1) {
|
|
4217
|
+
negotiateResponse.connectionToken = negotiateResponse.connectionId;
|
|
4218
|
+
}
|
|
4219
|
+
if (negotiateResponse.useStatefulReconnect && this._options._useStatefulReconnect !== true) {
|
|
4220
|
+
return Promise.reject(new FailedToNegotiateWithServerError("Client didn't negotiate Stateful Reconnect but the server did."));
|
|
4221
|
+
}
|
|
4222
|
+
return negotiateResponse;
|
|
4223
|
+
} catch (e) {
|
|
4224
|
+
let errorMessage = "Failed to complete negotiation with the server: " + e;
|
|
4225
|
+
if (e instanceof HttpError) {
|
|
4226
|
+
if (e.statusCode === 404) {
|
|
4227
|
+
errorMessage = errorMessage + " Either this is not a SignalR endpoint or there is a proxy blocking the connection.";
|
|
4228
|
+
}
|
|
4229
|
+
}
|
|
4230
|
+
this._logger.log(LogLevel.Error, errorMessage);
|
|
4231
|
+
return Promise.reject(new FailedToNegotiateWithServerError(errorMessage));
|
|
4232
|
+
}
|
|
4233
|
+
}
|
|
4234
|
+
_createConnectUrl(url, connectionToken) {
|
|
4235
|
+
if (!connectionToken) {
|
|
4236
|
+
return url;
|
|
4237
|
+
}
|
|
4238
|
+
return url + (url.indexOf("?") === -1 ? "?" : "&") + `id=${connectionToken}`;
|
|
4239
|
+
}
|
|
4240
|
+
async _createTransport(url, requestedTransport, negotiateResponse, requestedTransferFormat) {
|
|
4241
|
+
let connectUrl = this._createConnectUrl(url, negotiateResponse.connectionToken);
|
|
4242
|
+
if (this._isITransport(requestedTransport)) {
|
|
4243
|
+
this._logger.log(LogLevel.Debug, "Connection was provided an instance of ITransport, using that directly.");
|
|
4244
|
+
this.transport = requestedTransport;
|
|
4245
|
+
await this._startTransport(connectUrl, requestedTransferFormat);
|
|
4246
|
+
this.connectionId = negotiateResponse.connectionId;
|
|
4247
|
+
return;
|
|
4248
|
+
}
|
|
4249
|
+
const transportExceptions = [];
|
|
4250
|
+
const transports = negotiateResponse.availableTransports || [];
|
|
4251
|
+
let negotiate = negotiateResponse;
|
|
4252
|
+
for (const endpoint of transports) {
|
|
4253
|
+
const transportOrError = this._resolveTransportOrError(endpoint, requestedTransport, requestedTransferFormat, (negotiate === null || negotiate === void 0 ? void 0 : negotiate.useStatefulReconnect) === true);
|
|
4254
|
+
if (transportOrError instanceof Error) {
|
|
4255
|
+
transportExceptions.push(`${endpoint.transport} failed:`);
|
|
4256
|
+
transportExceptions.push(transportOrError);
|
|
4257
|
+
} else if (this._isITransport(transportOrError)) {
|
|
4258
|
+
this.transport = transportOrError;
|
|
4259
|
+
if (!negotiate) {
|
|
4260
|
+
try {
|
|
4261
|
+
negotiate = await this._getNegotiationResponse(url);
|
|
4262
|
+
} catch (ex) {
|
|
4263
|
+
return Promise.reject(ex);
|
|
4264
|
+
}
|
|
4265
|
+
connectUrl = this._createConnectUrl(url, negotiate.connectionToken);
|
|
4266
|
+
}
|
|
4267
|
+
try {
|
|
4268
|
+
await this._startTransport(connectUrl, requestedTransferFormat);
|
|
4269
|
+
this.connectionId = negotiate.connectionId;
|
|
4270
|
+
return;
|
|
4271
|
+
} catch (ex) {
|
|
4272
|
+
this._logger.log(LogLevel.Error, `Failed to start the transport '${endpoint.transport}': ${ex}`);
|
|
4273
|
+
negotiate = void 0;
|
|
4274
|
+
transportExceptions.push(new FailedToStartTransportError(`${endpoint.transport} failed: ${ex}`, HttpTransportType[endpoint.transport]));
|
|
4275
|
+
if (this._connectionState !== "Connecting") {
|
|
4276
|
+
const message = "Failed to select transport before stop() was called.";
|
|
4277
|
+
this._logger.log(LogLevel.Debug, message);
|
|
4278
|
+
return Promise.reject(new AbortError(message));
|
|
4279
|
+
}
|
|
4280
|
+
}
|
|
4281
|
+
}
|
|
4282
|
+
}
|
|
4283
|
+
if (transportExceptions.length > 0) {
|
|
4284
|
+
return Promise.reject(new AggregateErrors(`Unable to connect to the server with any of the available transports. ${transportExceptions.join(" ")}`, transportExceptions));
|
|
4285
|
+
}
|
|
4286
|
+
return Promise.reject(new Error("None of the transports supported by the client are supported by the server."));
|
|
4287
|
+
}
|
|
4288
|
+
_constructTransport(transport) {
|
|
4289
|
+
switch (transport) {
|
|
4290
|
+
case HttpTransportType.WebSockets:
|
|
4291
|
+
if (!this._options.WebSocket) {
|
|
4292
|
+
throw new Error("'WebSocket' is not supported in your environment.");
|
|
4293
|
+
}
|
|
4294
|
+
return new WebSocketTransport(this._httpClient, this._accessTokenFactory, this._logger, this._options.logMessageContent, this._options.WebSocket, this._options.headers || {});
|
|
4295
|
+
case HttpTransportType.ServerSentEvents:
|
|
4296
|
+
if (!this._options.EventSource) {
|
|
4297
|
+
throw new Error("'EventSource' is not supported in your environment.");
|
|
4298
|
+
}
|
|
4299
|
+
return new ServerSentEventsTransport(this._httpClient, this._httpClient._accessToken, this._logger, this._options);
|
|
4300
|
+
case HttpTransportType.LongPolling:
|
|
4301
|
+
return new LongPollingTransport(this._httpClient, this._logger, this._options);
|
|
4302
|
+
default:
|
|
4303
|
+
throw new Error(`Unknown transport: ${transport}.`);
|
|
4304
|
+
}
|
|
4305
|
+
}
|
|
4306
|
+
_startTransport(url, transferFormat) {
|
|
4307
|
+
this.transport.onreceive = this.onreceive;
|
|
4308
|
+
if (this.features.reconnect) {
|
|
4309
|
+
this.transport.onclose = async (e) => {
|
|
4310
|
+
let callStop = false;
|
|
4311
|
+
if (this.features.reconnect) {
|
|
4312
|
+
try {
|
|
4313
|
+
this.features.disconnected();
|
|
4314
|
+
await this.transport.connect(url, transferFormat);
|
|
4315
|
+
await this.features.resend();
|
|
4316
|
+
} catch {
|
|
4317
|
+
callStop = true;
|
|
4318
|
+
}
|
|
4319
|
+
} else {
|
|
4320
|
+
this._stopConnection(e);
|
|
4321
|
+
return;
|
|
4322
|
+
}
|
|
4323
|
+
if (callStop) {
|
|
4324
|
+
this._stopConnection(e);
|
|
4325
|
+
}
|
|
4326
|
+
};
|
|
4327
|
+
} else {
|
|
4328
|
+
this.transport.onclose = (e) => this._stopConnection(e);
|
|
4329
|
+
}
|
|
4330
|
+
return this.transport.connect(url, transferFormat);
|
|
4331
|
+
}
|
|
4332
|
+
_resolveTransportOrError(endpoint, requestedTransport, requestedTransferFormat, useStatefulReconnect) {
|
|
4333
|
+
const transport = HttpTransportType[endpoint.transport];
|
|
4334
|
+
if (transport === null || transport === void 0) {
|
|
4335
|
+
this._logger.log(LogLevel.Debug, `Skipping transport '${endpoint.transport}' because it is not supported by this client.`);
|
|
4336
|
+
return new Error(`Skipping transport '${endpoint.transport}' because it is not supported by this client.`);
|
|
4337
|
+
} else {
|
|
4338
|
+
if (transportMatches(requestedTransport, transport)) {
|
|
4339
|
+
const transferFormats = endpoint.transferFormats.map((s) => TransferFormat[s]);
|
|
4340
|
+
if (transferFormats.indexOf(requestedTransferFormat) >= 0) {
|
|
4341
|
+
if (transport === HttpTransportType.WebSockets && !this._options.WebSocket || transport === HttpTransportType.ServerSentEvents && !this._options.EventSource) {
|
|
4342
|
+
this._logger.log(LogLevel.Debug, `Skipping transport '${HttpTransportType[transport]}' because it is not supported in your environment.'`);
|
|
4343
|
+
return new UnsupportedTransportError(`'${HttpTransportType[transport]}' is not supported in your environment.`, transport);
|
|
4344
|
+
} else {
|
|
4345
|
+
this._logger.log(LogLevel.Debug, `Selecting transport '${HttpTransportType[transport]}'.`);
|
|
4346
|
+
try {
|
|
4347
|
+
this.features.reconnect = transport === HttpTransportType.WebSockets ? useStatefulReconnect : void 0;
|
|
4348
|
+
return this._constructTransport(transport);
|
|
4349
|
+
} catch (ex) {
|
|
4350
|
+
return ex;
|
|
4351
|
+
}
|
|
4352
|
+
}
|
|
4353
|
+
} else {
|
|
4354
|
+
this._logger.log(LogLevel.Debug, `Skipping transport '${HttpTransportType[transport]}' because it does not support the requested transfer format '${TransferFormat[requestedTransferFormat]}'.`);
|
|
4355
|
+
return new Error(`'${HttpTransportType[transport]}' does not support ${TransferFormat[requestedTransferFormat]}.`);
|
|
4356
|
+
}
|
|
4357
|
+
} else {
|
|
4358
|
+
this._logger.log(LogLevel.Debug, `Skipping transport '${HttpTransportType[transport]}' because it was disabled by the client.`);
|
|
4359
|
+
return new DisabledTransportError(`'${HttpTransportType[transport]}' is disabled by the client.`, transport);
|
|
4360
|
+
}
|
|
4361
|
+
}
|
|
4362
|
+
}
|
|
4363
|
+
_isITransport(transport) {
|
|
4364
|
+
return transport && typeof transport === "object" && "connect" in transport;
|
|
4365
|
+
}
|
|
4366
|
+
_stopConnection(error) {
|
|
4367
|
+
this._logger.log(LogLevel.Debug, `HttpConnection.stopConnection(${error}) called while in state ${this._connectionState}.`);
|
|
4368
|
+
this.transport = void 0;
|
|
4369
|
+
error = this._stopError || error;
|
|
4370
|
+
this._stopError = void 0;
|
|
4371
|
+
if (this._connectionState === "Disconnected") {
|
|
4372
|
+
this._logger.log(LogLevel.Debug, `Call to HttpConnection.stopConnection(${error}) was ignored because the connection is already in the disconnected state.`);
|
|
4373
|
+
return;
|
|
4374
|
+
}
|
|
4375
|
+
if (this._connectionState === "Connecting") {
|
|
4376
|
+
this._logger.log(LogLevel.Warning, `Call to HttpConnection.stopConnection(${error}) was ignored because the connection is still in the connecting state.`);
|
|
4377
|
+
throw new Error(`HttpConnection.stopConnection(${error}) was called while the connection is still in the connecting state.`);
|
|
4378
|
+
}
|
|
4379
|
+
if (this._connectionState === "Disconnecting") {
|
|
4380
|
+
this._stopPromiseResolver();
|
|
4381
|
+
}
|
|
4382
|
+
if (error) {
|
|
4383
|
+
this._logger.log(LogLevel.Error, `Connection disconnected with error '${error}'.`);
|
|
4384
|
+
} else {
|
|
4385
|
+
this._logger.log(LogLevel.Information, "Connection disconnected.");
|
|
4386
|
+
}
|
|
4387
|
+
if (this._sendQueue) {
|
|
4388
|
+
this._sendQueue.stop().catch((e) => {
|
|
4389
|
+
this._logger.log(LogLevel.Error, `TransportSendQueue.stop() threw error '${e}'.`);
|
|
4390
|
+
});
|
|
4391
|
+
this._sendQueue = void 0;
|
|
4392
|
+
}
|
|
4393
|
+
this.connectionId = void 0;
|
|
4394
|
+
this._connectionState = "Disconnected";
|
|
4395
|
+
if (this._connectionStarted) {
|
|
4396
|
+
this._connectionStarted = false;
|
|
4397
|
+
try {
|
|
4398
|
+
if (this.onclose) {
|
|
4399
|
+
this.onclose(error);
|
|
4400
|
+
}
|
|
4401
|
+
} catch (e) {
|
|
4402
|
+
this._logger.log(LogLevel.Error, `HttpConnection.onclose(${error}) threw error '${e}'.`);
|
|
4403
|
+
}
|
|
4404
|
+
}
|
|
4405
|
+
}
|
|
4406
|
+
_resolveUrl(url) {
|
|
4407
|
+
if (url.lastIndexOf("https://", 0) === 0 || url.lastIndexOf("http://", 0) === 0) {
|
|
4408
|
+
return url;
|
|
4409
|
+
}
|
|
4410
|
+
if (!Platform.isBrowser) {
|
|
4411
|
+
throw new Error(`Cannot resolve '${url}'.`);
|
|
4412
|
+
}
|
|
4413
|
+
const aTag = window.document.createElement("a");
|
|
4414
|
+
aTag.href = url;
|
|
4415
|
+
this._logger.log(LogLevel.Information, `Normalizing '${url}' to '${aTag.href}'.`);
|
|
4416
|
+
return aTag.href;
|
|
4417
|
+
}
|
|
4418
|
+
_resolveNegotiateUrl(url) {
|
|
4419
|
+
const negotiateUrl = new URL(url);
|
|
4420
|
+
if (negotiateUrl.pathname.endsWith("/")) {
|
|
4421
|
+
negotiateUrl.pathname += "negotiate";
|
|
4422
|
+
} else {
|
|
4423
|
+
negotiateUrl.pathname += "/negotiate";
|
|
4424
|
+
}
|
|
4425
|
+
const searchParams = new URLSearchParams(negotiateUrl.searchParams);
|
|
4426
|
+
if (!searchParams.has("negotiateVersion")) {
|
|
4427
|
+
searchParams.append("negotiateVersion", this._negotiateVersion.toString());
|
|
4428
|
+
}
|
|
4429
|
+
if (searchParams.has("useStatefulReconnect")) {
|
|
4430
|
+
if (searchParams.get("useStatefulReconnect") === "true") {
|
|
4431
|
+
this._options._useStatefulReconnect = true;
|
|
4432
|
+
}
|
|
4433
|
+
} else if (this._options._useStatefulReconnect === true) {
|
|
4434
|
+
searchParams.append("useStatefulReconnect", "true");
|
|
4435
|
+
}
|
|
4436
|
+
negotiateUrl.search = searchParams.toString();
|
|
4437
|
+
return negotiateUrl.toString();
|
|
4438
|
+
}
|
|
4439
|
+
};
|
|
4440
|
+
function transportMatches(requestedTransport, actualTransport) {
|
|
4441
|
+
return !requestedTransport || (actualTransport & requestedTransport) !== 0;
|
|
4442
|
+
}
|
|
4443
|
+
var TransportSendQueue = class _TransportSendQueue {
|
|
4444
|
+
constructor(_transport) {
|
|
4445
|
+
this._transport = _transport;
|
|
4446
|
+
this._buffer = [];
|
|
4447
|
+
this._executing = true;
|
|
4448
|
+
this._sendBufferedData = new PromiseSource();
|
|
4449
|
+
this._transportResult = new PromiseSource();
|
|
4450
|
+
this._sendLoopPromise = this._sendLoop();
|
|
4451
|
+
}
|
|
4452
|
+
send(data) {
|
|
4453
|
+
this._bufferData(data);
|
|
4454
|
+
if (!this._transportResult) {
|
|
4455
|
+
this._transportResult = new PromiseSource();
|
|
4456
|
+
}
|
|
4457
|
+
return this._transportResult.promise;
|
|
4458
|
+
}
|
|
4459
|
+
stop() {
|
|
4460
|
+
this._executing = false;
|
|
4461
|
+
this._sendBufferedData.resolve();
|
|
4462
|
+
return this._sendLoopPromise;
|
|
4463
|
+
}
|
|
4464
|
+
_bufferData(data) {
|
|
4465
|
+
if (this._buffer.length && typeof this._buffer[0] !== typeof data) {
|
|
4466
|
+
throw new Error(`Expected data to be of type ${typeof this._buffer} but was of type ${typeof data}`);
|
|
4467
|
+
}
|
|
4468
|
+
this._buffer.push(data);
|
|
4469
|
+
this._sendBufferedData.resolve();
|
|
4470
|
+
}
|
|
4471
|
+
async _sendLoop() {
|
|
4472
|
+
while (true) {
|
|
4473
|
+
await this._sendBufferedData.promise;
|
|
4474
|
+
if (!this._executing) {
|
|
4475
|
+
if (this._transportResult) {
|
|
4476
|
+
this._transportResult.reject("Connection stopped.");
|
|
4477
|
+
}
|
|
4478
|
+
break;
|
|
4479
|
+
}
|
|
4480
|
+
this._sendBufferedData = new PromiseSource();
|
|
4481
|
+
const transportResult = this._transportResult;
|
|
4482
|
+
this._transportResult = void 0;
|
|
4483
|
+
const data = typeof this._buffer[0] === "string" ? this._buffer.join("") : _TransportSendQueue._concatBuffers(this._buffer);
|
|
4484
|
+
this._buffer.length = 0;
|
|
4485
|
+
try {
|
|
4486
|
+
await this._transport.send(data);
|
|
4487
|
+
transportResult.resolve();
|
|
4488
|
+
} catch (error) {
|
|
4489
|
+
transportResult.reject(error);
|
|
4490
|
+
}
|
|
4491
|
+
}
|
|
4492
|
+
}
|
|
4493
|
+
static _concatBuffers(arrayBuffers) {
|
|
4494
|
+
const totalLength = arrayBuffers.map((b) => b.byteLength).reduce((a, b) => a + b);
|
|
4495
|
+
const result = new Uint8Array(totalLength);
|
|
4496
|
+
let offset = 0;
|
|
4497
|
+
for (const item of arrayBuffers) {
|
|
4498
|
+
result.set(new Uint8Array(item), offset);
|
|
4499
|
+
offset += item.byteLength;
|
|
4500
|
+
}
|
|
4501
|
+
return result.buffer;
|
|
4502
|
+
}
|
|
4503
|
+
};
|
|
4504
|
+
var PromiseSource = class {
|
|
4505
|
+
constructor() {
|
|
4506
|
+
this.promise = new Promise((resolve, reject) => [this._resolver, this._rejecter] = [resolve, reject]);
|
|
4507
|
+
}
|
|
4508
|
+
resolve() {
|
|
4509
|
+
this._resolver();
|
|
4510
|
+
}
|
|
4511
|
+
reject(reason) {
|
|
4512
|
+
this._rejecter(reason);
|
|
4513
|
+
}
|
|
4514
|
+
};
|
|
4515
|
+
|
|
4516
|
+
// node_modules/@microsoft/signalr/dist/esm/JsonHubProtocol.js
|
|
4517
|
+
var JSON_HUB_PROTOCOL_NAME = "json";
|
|
4518
|
+
var JsonHubProtocol = class {
|
|
4519
|
+
constructor() {
|
|
4520
|
+
this.name = JSON_HUB_PROTOCOL_NAME;
|
|
4521
|
+
this.version = 2;
|
|
4522
|
+
this.transferFormat = TransferFormat.Text;
|
|
4523
|
+
}
|
|
4524
|
+
/** Creates an array of {@link @microsoft/signalr.HubMessage} objects from the specified serialized representation.
|
|
4525
|
+
*
|
|
4526
|
+
* @param {string} input A string containing the serialized representation.
|
|
4527
|
+
* @param {ILogger} logger A logger that will be used to log messages that occur during parsing.
|
|
4528
|
+
*/
|
|
4529
|
+
parseMessages(input, logger) {
|
|
4530
|
+
if (typeof input !== "string") {
|
|
4531
|
+
throw new Error("Invalid input for JSON hub protocol. Expected a string.");
|
|
4532
|
+
}
|
|
4533
|
+
if (!input) {
|
|
4534
|
+
return [];
|
|
4535
|
+
}
|
|
4536
|
+
if (logger === null) {
|
|
4537
|
+
logger = NullLogger.instance;
|
|
4538
|
+
}
|
|
4539
|
+
const messages = TextMessageFormat.parse(input);
|
|
4540
|
+
const hubMessages = [];
|
|
4541
|
+
for (const message of messages) {
|
|
4542
|
+
const parsedMessage = JSON.parse(message);
|
|
4543
|
+
if (typeof parsedMessage.type !== "number") {
|
|
4544
|
+
throw new Error("Invalid payload.");
|
|
4545
|
+
}
|
|
4546
|
+
switch (parsedMessage.type) {
|
|
4547
|
+
case MessageType.Invocation:
|
|
4548
|
+
this._isInvocationMessage(parsedMessage);
|
|
4549
|
+
break;
|
|
4550
|
+
case MessageType.StreamItem:
|
|
4551
|
+
this._isStreamItemMessage(parsedMessage);
|
|
4552
|
+
break;
|
|
4553
|
+
case MessageType.Completion:
|
|
4554
|
+
this._isCompletionMessage(parsedMessage);
|
|
4555
|
+
break;
|
|
4556
|
+
case MessageType.Ping:
|
|
4557
|
+
break;
|
|
4558
|
+
case MessageType.Close:
|
|
4559
|
+
break;
|
|
4560
|
+
case MessageType.Ack:
|
|
4561
|
+
this._isAckMessage(parsedMessage);
|
|
4562
|
+
break;
|
|
4563
|
+
case MessageType.Sequence:
|
|
4564
|
+
this._isSequenceMessage(parsedMessage);
|
|
4565
|
+
break;
|
|
4566
|
+
default:
|
|
4567
|
+
logger.log(LogLevel.Information, "Unknown message type '" + parsedMessage.type + "' ignored.");
|
|
4568
|
+
continue;
|
|
4569
|
+
}
|
|
4570
|
+
hubMessages.push(parsedMessage);
|
|
4571
|
+
}
|
|
4572
|
+
return hubMessages;
|
|
4573
|
+
}
|
|
4574
|
+
/** Writes the specified {@link @microsoft/signalr.HubMessage} to a string and returns it.
|
|
4575
|
+
*
|
|
4576
|
+
* @param {HubMessage} message The message to write.
|
|
4577
|
+
* @returns {string} A string containing the serialized representation of the message.
|
|
4578
|
+
*/
|
|
4579
|
+
writeMessage(message) {
|
|
4580
|
+
return TextMessageFormat.write(JSON.stringify(message));
|
|
4581
|
+
}
|
|
4582
|
+
_isInvocationMessage(message) {
|
|
4583
|
+
this._assertNotEmptyString(message.target, "Invalid payload for Invocation message.");
|
|
4584
|
+
if (message.invocationId !== void 0) {
|
|
4585
|
+
this._assertNotEmptyString(message.invocationId, "Invalid payload for Invocation message.");
|
|
4586
|
+
}
|
|
4587
|
+
}
|
|
4588
|
+
_isStreamItemMessage(message) {
|
|
4589
|
+
this._assertNotEmptyString(message.invocationId, "Invalid payload for StreamItem message.");
|
|
4590
|
+
if (message.item === void 0) {
|
|
4591
|
+
throw new Error("Invalid payload for StreamItem message.");
|
|
4592
|
+
}
|
|
4593
|
+
}
|
|
4594
|
+
_isCompletionMessage(message) {
|
|
4595
|
+
if (message.result && message.error) {
|
|
4596
|
+
throw new Error("Invalid payload for Completion message.");
|
|
4597
|
+
}
|
|
4598
|
+
if (!message.result && message.error) {
|
|
4599
|
+
this._assertNotEmptyString(message.error, "Invalid payload for Completion message.");
|
|
4600
|
+
}
|
|
4601
|
+
this._assertNotEmptyString(message.invocationId, "Invalid payload for Completion message.");
|
|
4602
|
+
}
|
|
4603
|
+
_isAckMessage(message) {
|
|
4604
|
+
if (typeof message.sequenceId !== "number") {
|
|
4605
|
+
throw new Error("Invalid SequenceId for Ack message.");
|
|
4606
|
+
}
|
|
4607
|
+
}
|
|
4608
|
+
_isSequenceMessage(message) {
|
|
4609
|
+
if (typeof message.sequenceId !== "number") {
|
|
4610
|
+
throw new Error("Invalid SequenceId for Sequence message.");
|
|
4611
|
+
}
|
|
4612
|
+
}
|
|
4613
|
+
_assertNotEmptyString(value, errorMessage) {
|
|
4614
|
+
if (typeof value !== "string" || value === "") {
|
|
4615
|
+
throw new Error(errorMessage);
|
|
4616
|
+
}
|
|
4617
|
+
}
|
|
4618
|
+
};
|
|
4619
|
+
|
|
4620
|
+
// node_modules/@microsoft/signalr/dist/esm/HubConnectionBuilder.js
|
|
4621
|
+
var LogLevelNameMapping = {
|
|
4622
|
+
trace: LogLevel.Trace,
|
|
4623
|
+
debug: LogLevel.Debug,
|
|
4624
|
+
info: LogLevel.Information,
|
|
4625
|
+
information: LogLevel.Information,
|
|
4626
|
+
warn: LogLevel.Warning,
|
|
4627
|
+
warning: LogLevel.Warning,
|
|
4628
|
+
error: LogLevel.Error,
|
|
4629
|
+
critical: LogLevel.Critical,
|
|
4630
|
+
none: LogLevel.None
|
|
4631
|
+
};
|
|
4632
|
+
function parseLogLevel(name) {
|
|
4633
|
+
const mapping = LogLevelNameMapping[name.toLowerCase()];
|
|
4634
|
+
if (typeof mapping !== "undefined") {
|
|
4635
|
+
return mapping;
|
|
4636
|
+
} else {
|
|
4637
|
+
throw new Error(`Unknown log level: ${name}`);
|
|
4638
|
+
}
|
|
4639
|
+
}
|
|
4640
|
+
var HubConnectionBuilder = class {
|
|
4641
|
+
configureLogging(logging) {
|
|
4642
|
+
Arg.isRequired(logging, "logging");
|
|
4643
|
+
if (isLogger(logging)) {
|
|
4644
|
+
this.logger = logging;
|
|
4645
|
+
} else if (typeof logging === "string") {
|
|
4646
|
+
const logLevel = parseLogLevel(logging);
|
|
4647
|
+
this.logger = new ConsoleLogger(logLevel);
|
|
4648
|
+
} else {
|
|
4649
|
+
this.logger = new ConsoleLogger(logging);
|
|
4650
|
+
}
|
|
4651
|
+
return this;
|
|
4652
|
+
}
|
|
4653
|
+
withUrl(url, transportTypeOrOptions) {
|
|
4654
|
+
Arg.isRequired(url, "url");
|
|
4655
|
+
Arg.isNotEmpty(url, "url");
|
|
4656
|
+
this.url = url;
|
|
4657
|
+
if (typeof transportTypeOrOptions === "object") {
|
|
4658
|
+
this.httpConnectionOptions = { ...this.httpConnectionOptions, ...transportTypeOrOptions };
|
|
4659
|
+
} else {
|
|
4660
|
+
this.httpConnectionOptions = {
|
|
4661
|
+
...this.httpConnectionOptions,
|
|
4662
|
+
transport: transportTypeOrOptions
|
|
4663
|
+
};
|
|
4664
|
+
}
|
|
4665
|
+
return this;
|
|
4666
|
+
}
|
|
4667
|
+
/** Configures the {@link @microsoft/signalr.HubConnection} to use the specified Hub Protocol.
|
|
4668
|
+
*
|
|
4669
|
+
* @param {IHubProtocol} protocol The {@link @microsoft/signalr.IHubProtocol} implementation to use.
|
|
4670
|
+
*/
|
|
4671
|
+
withHubProtocol(protocol) {
|
|
4672
|
+
Arg.isRequired(protocol, "protocol");
|
|
4673
|
+
this.protocol = protocol;
|
|
4674
|
+
return this;
|
|
4675
|
+
}
|
|
4676
|
+
withAutomaticReconnect(retryDelaysOrReconnectPolicy) {
|
|
4677
|
+
if (this.reconnectPolicy) {
|
|
4678
|
+
throw new Error("A reconnectPolicy has already been set.");
|
|
4679
|
+
}
|
|
4680
|
+
if (!retryDelaysOrReconnectPolicy) {
|
|
4681
|
+
this.reconnectPolicy = new DefaultReconnectPolicy();
|
|
4682
|
+
} else if (Array.isArray(retryDelaysOrReconnectPolicy)) {
|
|
4683
|
+
this.reconnectPolicy = new DefaultReconnectPolicy(retryDelaysOrReconnectPolicy);
|
|
4684
|
+
} else {
|
|
4685
|
+
this.reconnectPolicy = retryDelaysOrReconnectPolicy;
|
|
4686
|
+
}
|
|
4687
|
+
return this;
|
|
4688
|
+
}
|
|
4689
|
+
/** Configures {@link @microsoft/signalr.HubConnection.serverTimeoutInMilliseconds} for the {@link @microsoft/signalr.HubConnection}.
|
|
4690
|
+
*
|
|
4691
|
+
* @returns The {@link @microsoft/signalr.HubConnectionBuilder} instance, for chaining.
|
|
4692
|
+
*/
|
|
4693
|
+
withServerTimeout(milliseconds) {
|
|
4694
|
+
Arg.isRequired(milliseconds, "milliseconds");
|
|
4695
|
+
this._serverTimeoutInMilliseconds = milliseconds;
|
|
4696
|
+
return this;
|
|
4697
|
+
}
|
|
4698
|
+
/** Configures {@link @microsoft/signalr.HubConnection.keepAliveIntervalInMilliseconds} for the {@link @microsoft/signalr.HubConnection}.
|
|
4699
|
+
*
|
|
4700
|
+
* @returns The {@link @microsoft/signalr.HubConnectionBuilder} instance, for chaining.
|
|
4701
|
+
*/
|
|
4702
|
+
withKeepAliveInterval(milliseconds) {
|
|
4703
|
+
Arg.isRequired(milliseconds, "milliseconds");
|
|
4704
|
+
this._keepAliveIntervalInMilliseconds = milliseconds;
|
|
4705
|
+
return this;
|
|
4706
|
+
}
|
|
4707
|
+
/** Enables and configures options for the Stateful Reconnect feature.
|
|
4708
|
+
*
|
|
4709
|
+
* @returns The {@link @microsoft/signalr.HubConnectionBuilder} instance, for chaining.
|
|
4710
|
+
*/
|
|
4711
|
+
withStatefulReconnect(options) {
|
|
4712
|
+
if (this.httpConnectionOptions === void 0) {
|
|
4713
|
+
this.httpConnectionOptions = {};
|
|
4714
|
+
}
|
|
4715
|
+
this.httpConnectionOptions._useStatefulReconnect = true;
|
|
4716
|
+
this._statefulReconnectBufferSize = options === null || options === void 0 ? void 0 : options.bufferSize;
|
|
4717
|
+
return this;
|
|
4718
|
+
}
|
|
4719
|
+
/** Creates a {@link @microsoft/signalr.HubConnection} from the configuration options specified in this builder.
|
|
4720
|
+
*
|
|
4721
|
+
* @returns {HubConnection} The configured {@link @microsoft/signalr.HubConnection}.
|
|
4722
|
+
*/
|
|
4723
|
+
build() {
|
|
4724
|
+
const httpConnectionOptions = this.httpConnectionOptions || {};
|
|
4725
|
+
if (httpConnectionOptions.logger === void 0) {
|
|
4726
|
+
httpConnectionOptions.logger = this.logger;
|
|
4727
|
+
}
|
|
4728
|
+
if (!this.url) {
|
|
4729
|
+
throw new Error("The 'HubConnectionBuilder.withUrl' method must be called before building the connection.");
|
|
4730
|
+
}
|
|
4731
|
+
const connection = new HttpConnection(this.url, httpConnectionOptions);
|
|
4732
|
+
return HubConnection.create(connection, this.logger || NullLogger.instance, this.protocol || new JsonHubProtocol(), this.reconnectPolicy, this._serverTimeoutInMilliseconds, this._keepAliveIntervalInMilliseconds, this._statefulReconnectBufferSize);
|
|
4733
|
+
}
|
|
4734
|
+
};
|
|
4735
|
+
function isLogger(logger) {
|
|
4736
|
+
return logger.log !== void 0;
|
|
4737
|
+
}
|
|
4738
|
+
|
|
4739
|
+
// src/hooks/useSignalRConnection.ts
|
|
4740
|
+
function useSignalRConnection(hubUrl, options = {}) {
|
|
4741
|
+
const {
|
|
4742
|
+
queryParams,
|
|
4743
|
+
logLevel = LogLevel.Warning,
|
|
4744
|
+
autoConnect = true,
|
|
4745
|
+
reconnectOnAuth = true,
|
|
4746
|
+
debug = false
|
|
4747
|
+
} = options;
|
|
4748
|
+
const { user, isAuthenticated } = useAuth();
|
|
4749
|
+
const [connection, setConnection] = react.useState(null);
|
|
4750
|
+
const [connectionState, setConnectionState] = react.useState(HubConnectionState.Disconnected);
|
|
4751
|
+
const [error, setError] = react.useState(null);
|
|
4752
|
+
const reconnectAttemptRef = react.useRef(false);
|
|
4753
|
+
const log = react.useCallback(
|
|
4754
|
+
(message, ...args) => {
|
|
4755
|
+
if (debug) {
|
|
4756
|
+
console.log(`[useSignalRConnection] ${message}`, ...args);
|
|
4757
|
+
}
|
|
4758
|
+
},
|
|
4759
|
+
[debug]
|
|
4760
|
+
);
|
|
4761
|
+
react.useEffect(() => {
|
|
4762
|
+
if (!hubUrl) {
|
|
4763
|
+
log("Hub URL is required");
|
|
4764
|
+
return;
|
|
4765
|
+
}
|
|
4766
|
+
log("Building SignalR connection to:", hubUrl);
|
|
4767
|
+
const builder = new HubConnectionBuilder().withUrl(hubUrl, {
|
|
4768
|
+
accessTokenFactory: async () => {
|
|
4769
|
+
const token = user?.access_token;
|
|
4770
|
+
log("Access token factory called, token length:", token?.length ?? 0);
|
|
4771
|
+
return token || "";
|
|
4772
|
+
},
|
|
4773
|
+
...queryParams
|
|
4774
|
+
}).withAutomaticReconnect().configureLogging(logLevel);
|
|
4775
|
+
const newConnection = builder.build();
|
|
4776
|
+
newConnection.onclose((err) => {
|
|
4777
|
+
log("Connection closed", err);
|
|
4778
|
+
setConnectionState(HubConnectionState.Disconnected);
|
|
4779
|
+
if (err) {
|
|
4780
|
+
setError(err);
|
|
4781
|
+
}
|
|
4782
|
+
});
|
|
4783
|
+
newConnection.onreconnecting((err) => {
|
|
4784
|
+
log("Connection reconnecting", err);
|
|
4785
|
+
setConnectionState(HubConnectionState.Reconnecting);
|
|
4786
|
+
if (err) {
|
|
4787
|
+
setError(err);
|
|
4788
|
+
}
|
|
4789
|
+
});
|
|
4790
|
+
newConnection.onreconnected((connectionId) => {
|
|
4791
|
+
log("Connection reconnected, connection ID:", connectionId);
|
|
4792
|
+
setConnectionState(HubConnectionState.Connected);
|
|
4793
|
+
setError(null);
|
|
4794
|
+
});
|
|
4795
|
+
setConnection(newConnection);
|
|
4796
|
+
log("SignalR connection built");
|
|
4797
|
+
return () => {
|
|
4798
|
+
log("Cleaning up connection");
|
|
4799
|
+
if (newConnection.state !== HubConnectionState.Disconnected) {
|
|
4800
|
+
newConnection.stop().catch((err) => {
|
|
4801
|
+
console.error("[useSignalRConnection] Error stopping connection:", err);
|
|
4802
|
+
});
|
|
4803
|
+
}
|
|
4804
|
+
};
|
|
4805
|
+
}, [hubUrl, queryParams, logLevel, user, log]);
|
|
4806
|
+
const connect = react.useCallback(async () => {
|
|
4807
|
+
if (!connection) {
|
|
4808
|
+
log("Cannot connect: connection is null");
|
|
4809
|
+
return;
|
|
4810
|
+
}
|
|
4811
|
+
if (connection.state === HubConnectionState.Connected) {
|
|
4812
|
+
log("Already connected");
|
|
4813
|
+
return;
|
|
4814
|
+
}
|
|
4815
|
+
if (connection.state === HubConnectionState.Connecting) {
|
|
4816
|
+
log("Already connecting");
|
|
4817
|
+
return;
|
|
4818
|
+
}
|
|
4819
|
+
try {
|
|
4820
|
+
log("Connecting to hub...");
|
|
4821
|
+
setConnectionState(HubConnectionState.Connecting);
|
|
4822
|
+
setError(null);
|
|
4823
|
+
await connection.start();
|
|
4824
|
+
setConnectionState(HubConnectionState.Connected);
|
|
4825
|
+
log("Connected successfully");
|
|
4826
|
+
} catch (err) {
|
|
4827
|
+
const error2 = err instanceof Error ? err : new Error(String(err));
|
|
4828
|
+
log("Connection failed:", error2);
|
|
4829
|
+
setError(error2);
|
|
4830
|
+
setConnectionState(HubConnectionState.Disconnected);
|
|
4831
|
+
throw error2;
|
|
4832
|
+
}
|
|
4833
|
+
}, [connection, log]);
|
|
4834
|
+
const disconnect = react.useCallback(async () => {
|
|
4835
|
+
if (!connection) {
|
|
4836
|
+
log("Cannot disconnect: connection is null");
|
|
4837
|
+
return;
|
|
4838
|
+
}
|
|
4839
|
+
if (connection.state === HubConnectionState.Disconnected) {
|
|
4840
|
+
log("Already disconnected");
|
|
4841
|
+
return;
|
|
4842
|
+
}
|
|
4843
|
+
try {
|
|
4844
|
+
log("Disconnecting from hub...");
|
|
4845
|
+
await connection.stop();
|
|
4846
|
+
setConnectionState(HubConnectionState.Disconnected);
|
|
4847
|
+
log("Disconnected successfully");
|
|
4848
|
+
} catch (err) {
|
|
4849
|
+
const error2 = err instanceof Error ? err : new Error(String(err));
|
|
4850
|
+
log("Disconnect failed:", error2);
|
|
4851
|
+
setError(error2);
|
|
4852
|
+
throw error2;
|
|
4853
|
+
}
|
|
4854
|
+
}, [connection, log]);
|
|
4855
|
+
const invoke = react.useCallback(
|
|
4856
|
+
async (methodName, ...args) => {
|
|
4857
|
+
if (!connection) {
|
|
4858
|
+
throw new Error("Cannot invoke: connection is null");
|
|
4859
|
+
}
|
|
4860
|
+
if (connection.state !== HubConnectionState.Connected) {
|
|
4861
|
+
throw new Error(`Cannot invoke: connection is ${connection.state}`);
|
|
4862
|
+
}
|
|
4863
|
+
log("Invoking method:", methodName, "with args:", args);
|
|
4864
|
+
return connection.invoke(methodName, ...args);
|
|
4865
|
+
},
|
|
4866
|
+
[connection, log]
|
|
4867
|
+
);
|
|
4868
|
+
const on = react.useCallback(
|
|
4869
|
+
(methodName, handler) => {
|
|
4870
|
+
if (!connection) {
|
|
4871
|
+
log("Cannot register handler: connection is null");
|
|
4872
|
+
return () => {
|
|
4873
|
+
};
|
|
4874
|
+
}
|
|
4875
|
+
log("Registering handler for method:", methodName);
|
|
4876
|
+
connection.on(methodName, handler);
|
|
4877
|
+
return () => {
|
|
4878
|
+
log("Unregistering handler for method:", methodName);
|
|
4879
|
+
connection.off(methodName, handler);
|
|
4880
|
+
};
|
|
4881
|
+
},
|
|
4882
|
+
[connection, log]
|
|
4883
|
+
);
|
|
4884
|
+
react.useEffect(() => {
|
|
4885
|
+
if (!connection || !autoConnect) {
|
|
4886
|
+
return;
|
|
4887
|
+
}
|
|
4888
|
+
if (isAuthenticated && connection.state === HubConnectionState.Disconnected) {
|
|
4889
|
+
log("Auto-connecting (authenticated)");
|
|
4890
|
+
connect().catch((err) => {
|
|
4891
|
+
log("Auto-connect failed:", err);
|
|
4892
|
+
});
|
|
4893
|
+
}
|
|
4894
|
+
}, [connection, isAuthenticated, autoConnect, connect, log]);
|
|
4895
|
+
react.useEffect(() => {
|
|
4896
|
+
if (!connection || !reconnectOnAuth || reconnectAttemptRef.current) {
|
|
4897
|
+
return;
|
|
4898
|
+
}
|
|
4899
|
+
const handleAuthChange = async () => {
|
|
4900
|
+
if (isAuthenticated && connection.state === HubConnectionState.Disconnected) {
|
|
4901
|
+
reconnectAttemptRef.current = true;
|
|
4902
|
+
log("Reconnecting on auth state change");
|
|
4903
|
+
try {
|
|
4904
|
+
await connect();
|
|
4905
|
+
} catch (err) {
|
|
4906
|
+
log("Reconnect on auth change failed:", err);
|
|
4907
|
+
} finally {
|
|
4908
|
+
reconnectAttemptRef.current = false;
|
|
4909
|
+
}
|
|
4910
|
+
} else if (!isAuthenticated && connection.state === HubConnectionState.Connected) {
|
|
4911
|
+
log("Disconnecting on auth state change");
|
|
4912
|
+
await disconnect();
|
|
4913
|
+
}
|
|
4914
|
+
};
|
|
4915
|
+
handleAuthChange();
|
|
4916
|
+
}, [isAuthenticated, connection, reconnectOnAuth, connect, disconnect, log]);
|
|
4917
|
+
return {
|
|
4918
|
+
connection,
|
|
4919
|
+
connectionState,
|
|
4920
|
+
isConnected: connectionState === HubConnectionState.Connected,
|
|
4921
|
+
isConnecting: connectionState === HubConnectionState.Connecting,
|
|
4922
|
+
error,
|
|
4923
|
+
connect,
|
|
4924
|
+
disconnect,
|
|
4925
|
+
invoke,
|
|
4926
|
+
on
|
|
4927
|
+
};
|
|
4928
|
+
}
|
|
4929
|
+
|
|
1887
4930
|
exports.CONFIG_PRESETS = CONFIG_PRESETS;
|
|
1888
4931
|
exports.DeviceLogin = DeviceLogin;
|
|
1889
4932
|
exports.KeycloakConfigBuilder = KeycloakConfigBuilder;
|
|
@@ -1911,6 +4954,7 @@ exports.useKeycloakStatus = useKeycloakStatus;
|
|
|
1911
4954
|
exports.useProtectedFetch = useProtectedFetch;
|
|
1912
4955
|
exports.useRoles = useRoles;
|
|
1913
4956
|
exports.useScopes = useScopes;
|
|
4957
|
+
exports.useSignalRConnection = useSignalRConnection;
|
|
1914
4958
|
exports.useTokenLifecycle = useTokenLifecycle;
|
|
1915
4959
|
//# sourceMappingURL=index.js.map
|
|
1916
4960
|
//# sourceMappingURL=index.js.map
|