videomail-client 16.6.0 → 16.7.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/cjs/index.cjs
CHANGED
|
@@ -7212,7 +7212,7 @@ var __webpack_modules__ = {
|
|
|
7212
7212
|
const qs = __webpack_require__("b");
|
|
7213
7213
|
const RequestBase = __webpack_require__("d");
|
|
7214
7214
|
const { isObject, mixin, hasOwn, isSafeKey } = __webpack_require__("Dp");
|
|
7215
|
-
const ResponseBase = __webpack_require__("
|
|
7215
|
+
const ResponseBase = __webpack_require__("e");
|
|
7216
7216
|
const Agent = __webpack_require__("pf");
|
|
7217
7217
|
function noop() {}
|
|
7218
7218
|
module.exports = function(method, url) {
|
|
@@ -7926,7 +7926,7 @@ var __webpack_modules__ = {
|
|
|
7926
7926
|
}, this._responseTimeout);
|
|
7927
7927
|
};
|
|
7928
7928
|
},
|
|
7929
|
-
|
|
7929
|
+
e (module, __unused_rspack_exports, __webpack_require__) {
|
|
7930
7930
|
"use strict";
|
|
7931
7931
|
const utils = __webpack_require__("Dp");
|
|
7932
7932
|
module.exports = ResponseBase;
|
|
@@ -10637,7 +10637,7 @@ var __webpack_modules__ = {
|
|
|
10637
10637
|
return i[1];
|
|
10638
10638
|
};
|
|
10639
10639
|
},
|
|
10640
|
-
|
|
10640
|
+
RR (module) {
|
|
10641
10641
|
"use strict";
|
|
10642
10642
|
var stylesInDOM = [];
|
|
10643
10643
|
function getIndexByIdentifier(identifier) {
|
|
@@ -11138,7 +11138,7 @@ var __webpack_exports__ = {};
|
|
|
11138
11138
|
var client = __webpack_require__("Q");
|
|
11139
11139
|
var client_default = /*#__PURE__*/ __webpack_require__.n(client);
|
|
11140
11140
|
var package_namespaceObject = {
|
|
11141
|
-
rE: "16.
|
|
11141
|
+
rE: "16.7.0"
|
|
11142
11142
|
};
|
|
11143
11143
|
function isAudioEnabled(options) {
|
|
11144
11144
|
return Boolean(options.audio.enabled);
|
|
@@ -15855,7 +15855,7 @@ var __webpack_exports__ = {};
|
|
|
15855
15855
|
return newOptions;
|
|
15856
15856
|
}
|
|
15857
15857
|
const options_mergeWithDefaultOptions = mergeWithDefaultOptions;
|
|
15858
|
-
var injectStylesIntoStyleTag = __webpack_require__("
|
|
15858
|
+
var injectStylesIntoStyleTag = __webpack_require__("RR");
|
|
15859
15859
|
var injectStylesIntoStyleTag_default = /*#__PURE__*/ __webpack_require__.n(injectStylesIntoStyleTag);
|
|
15860
15860
|
var styleDomAPI = __webpack_require__("Bd");
|
|
15861
15861
|
var styleDomAPI_default = /*#__PURE__*/ __webpack_require__.n(styleDomAPI);
|
|
@@ -19303,6 +19303,18 @@ var __webpack_exports__ = {};
|
|
|
19303
19303
|
canvas_to_buffer_modern_r.atob = void 0;
|
|
19304
19304
|
var websocket_stream_stream = __webpack_require__("U");
|
|
19305
19305
|
var stream_default = /*#__PURE__*/ __webpack_require__.n(websocket_stream_stream);
|
|
19306
|
+
function isAutomatedUserAgent(userAgent = navigator.userAgent) {
|
|
19307
|
+
return /bot|crawler|spider|headlesschrome|phantomjs|puppeteer|playwright/iu.test(userAgent);
|
|
19308
|
+
}
|
|
19309
|
+
const util_isAutomatedUserAgent = isAutomatedUserAgent;
|
|
19310
|
+
function getAutomationSignals() {
|
|
19311
|
+
const webdriver = navigator.webdriver;
|
|
19312
|
+
return {
|
|
19313
|
+
webdriver: true === webdriver,
|
|
19314
|
+
userAgentMatched: util_isAutomatedUserAgent()
|
|
19315
|
+
};
|
|
19316
|
+
}
|
|
19317
|
+
const util_getAutomationSignals = getAutomationSignals;
|
|
19306
19318
|
function getEdgeCodes(value, amount, fromEnd) {
|
|
19307
19319
|
const chars = fromEnd ? value.slice(-amount) : value.slice(0, amount);
|
|
19308
19320
|
const codes = Array.from(chars, (char)=>String(char.codePointAt(0))).join(".");
|
|
@@ -19330,15 +19342,16 @@ var __webpack_exports__ = {};
|
|
|
19330
19342
|
if (languageList.length > 0) return languageList.join(",");
|
|
19331
19343
|
return navigator.language || "none";
|
|
19332
19344
|
}
|
|
19333
|
-
function
|
|
19345
|
+
function getDiagnosticSignals(probeBase, probeSimpleQuery) {
|
|
19334
19346
|
const reasons = [];
|
|
19335
|
-
|
|
19336
|
-
if (
|
|
19347
|
+
const automation = util_getAutomationSignals();
|
|
19348
|
+
if (automation.webdriver) reasons.push("webdriver=true");
|
|
19349
|
+
if (automation.userAgentMatched) reasons.push("headless_ua_marker");
|
|
19337
19350
|
if (0 === navigator.languages.length) reasons.push("no_languages");
|
|
19338
19351
|
if ("ok" !== probeBase) reasons.push("probe_base_failed");
|
|
19339
19352
|
if ("ok" !== probeSimpleQuery) reasons.push("probe_simple_query_failed");
|
|
19340
19353
|
return {
|
|
19341
|
-
looksAutomated:
|
|
19354
|
+
looksAutomated: automation.webdriver || automation.userAgentMatched,
|
|
19342
19355
|
reasons: reasons.length > 0 ? reasons.join(",") : "none"
|
|
19343
19356
|
};
|
|
19344
19357
|
}
|
|
@@ -19355,7 +19368,7 @@ var __webpack_exports__ = {};
|
|
|
19355
19368
|
const probeBase = probeWebSocketConstructor("wss://videomail.io");
|
|
19356
19369
|
const probeWithSimpleQuery = probeWebSocketConstructor("wss://videomail.io/?a=b");
|
|
19357
19370
|
const languages = getLanguagesValue();
|
|
19358
|
-
const automationSignals =
|
|
19371
|
+
const automationSignals = getDiagnosticSignals(probeBase, probeWithSimpleQuery);
|
|
19359
19372
|
const diagnosticPairs = [
|
|
19360
19373
|
`webdriver=${String(navigator.webdriver)}`,
|
|
19361
19374
|
`wsCtorNative=${String(wsCtorNative)}`,
|
|
@@ -19382,10 +19395,6 @@ var __webpack_exports__ = {};
|
|
|
19382
19395
|
};
|
|
19383
19396
|
}
|
|
19384
19397
|
const error_getWebSocketDiagnostic = getWebSocketDiagnostic;
|
|
19385
|
-
function isAutomatedUserAgent(userAgent = navigator.userAgent) {
|
|
19386
|
-
return /bot|crawler|spider|headlesschrome|phantomjs|puppeteer|playwright/iu.test(userAgent);
|
|
19387
|
-
}
|
|
19388
|
-
const util_isAutomatedUserAgent = isAutomatedUserAgent;
|
|
19389
19398
|
function boundedWriteQueue_define_property(obj, key, value) {
|
|
19390
19399
|
if (key in obj) Object.defineProperty(obj, key, {
|
|
19391
19400
|
value: value,
|
|
@@ -19581,6 +19590,9 @@ var __webpack_exports__ = {};
|
|
|
19581
19590
|
explanation: "The server connection closed before this recording completed. It cannot be safely resumed, so it has been stopped. Please start a new recording.",
|
|
19582
19591
|
options: this.options,
|
|
19583
19592
|
cause: {
|
|
19593
|
+
transportPhase: "recording",
|
|
19594
|
+
mediaTransmissionStarted: true,
|
|
19595
|
+
automation: util_getAutomationSignals(),
|
|
19584
19596
|
unconfirmedFrames,
|
|
19585
19597
|
unconfirmedSamples
|
|
19586
19598
|
}
|
|
@@ -19648,46 +19660,54 @@ var __webpack_exports__ = {};
|
|
|
19648
19660
|
this.resumeAfterDrain = false;
|
|
19649
19661
|
this.reconnecting = true;
|
|
19650
19662
|
this.initSocket();
|
|
19651
|
-
} else if (this.shouldReportStreamClose())
|
|
19652
|
-
this.
|
|
19653
|
-
|
|
19654
|
-
|
|
19655
|
-
|
|
19656
|
-
|
|
19663
|
+
} else if (this.shouldReportStreamClose()) {
|
|
19664
|
+
const stream = this.stream;
|
|
19665
|
+
window.setTimeout(()=>{
|
|
19666
|
+
if (this.stream === stream) this.handleConnectionFailure({
|
|
19667
|
+
url2Connect,
|
|
19668
|
+
cause: "closed"
|
|
19669
|
+
});
|
|
19670
|
+
}, 0);
|
|
19671
|
+
}
|
|
19657
19672
|
}
|
|
19658
19673
|
shouldIgnoreStreamClose() {
|
|
19659
|
-
return this.recordingTransportFailed || Boolean(this.unloaded) || this.validate();
|
|
19674
|
+
return this.recordingTransportFailed || Boolean(this.unloaded) || this.validate() || this.blocking && !this.mediaTransmissionStarted;
|
|
19675
|
+
}
|
|
19676
|
+
closeIdleConnection(reason) {
|
|
19677
|
+
if (this.mediaTransmissionStarted) return;
|
|
19678
|
+
this.options.logger.debug(string_summarize("Recorder: closing idle connection", {
|
|
19679
|
+
reason,
|
|
19680
|
+
connected: this.connected,
|
|
19681
|
+
connecting: this.connecting,
|
|
19682
|
+
visibilityState: document.visibilityState
|
|
19683
|
+
}));
|
|
19684
|
+
this.connected = this.connecting = this.reconnecting = false;
|
|
19685
|
+
this.clearConnectionTimeout();
|
|
19686
|
+
this.clearReconnectTimeout();
|
|
19687
|
+
this.stopPings();
|
|
19688
|
+
this.discardSocket();
|
|
19660
19689
|
}
|
|
19661
19690
|
handleStreamError(url2Connect, err) {
|
|
19662
|
-
var _this_lastSocketError;
|
|
19663
19691
|
if ("u" > typeof Event && err instanceof Event) this.lastSocketError = error_getEventDetails(err);
|
|
19664
19692
|
else this.lastSocketError = serializeError(err);
|
|
19665
19693
|
const debugLine = string_summarize(`${PIPE_SYMBOL}Stream *error* event emitted:`, {
|
|
19666
19694
|
error: serializeError(err)
|
|
19667
19695
|
});
|
|
19668
19696
|
this.options.logger.debug(debugLine);
|
|
19669
|
-
if (this.
|
|
19697
|
+
if (this.shouldIgnoreStreamClose()) {
|
|
19670
19698
|
this.connected = false;
|
|
19671
19699
|
this.stopPings();
|
|
19672
19700
|
this.discardSocket();
|
|
19673
19701
|
return;
|
|
19674
19702
|
}
|
|
19675
|
-
if (
|
|
19703
|
+
if (this.mediaTransmissionStarted) return void this.failInterruptedRecording();
|
|
19704
|
+
this.reconnecting || (this.reconnecting = this.canReconnectAfterStreamClose());
|
|
19705
|
+
this.connected = false;
|
|
19706
|
+
this.stopPings();
|
|
19707
|
+
this.handleConnectionFailure({
|
|
19676
19708
|
url2Connect,
|
|
19677
19709
|
cause: "error"
|
|
19678
19710
|
});
|
|
19679
|
-
const streamError = err instanceof Error ? err : new Error("WebSocket stream emitted an error event", {
|
|
19680
|
-
cause: null != (_this_lastSocketError = this.lastSocketError) ? _this_lastSocketError : err
|
|
19681
|
-
});
|
|
19682
|
-
if (this.mediaTransmissionStarted) return void this.failInterruptedRecording();
|
|
19683
|
-
this.emit("ERROR", {
|
|
19684
|
-
err: error_createError({
|
|
19685
|
-
message: "WebSocket stream error",
|
|
19686
|
-
explanation: `The WebSocket stream emitted an error event. Details: ${string_pretty(err)}`,
|
|
19687
|
-
options: this.options,
|
|
19688
|
-
exc: streamError
|
|
19689
|
-
})
|
|
19690
|
-
});
|
|
19691
19711
|
}
|
|
19692
19712
|
sendPings() {
|
|
19693
19713
|
this.stopPings();
|
|
@@ -19748,6 +19768,7 @@ var __webpack_exports__ = {};
|
|
|
19748
19768
|
this.connectionFailed = true;
|
|
19749
19769
|
this.connecting = false;
|
|
19750
19770
|
this.reconnecting = false;
|
|
19771
|
+
const reconnectAttempts = this.reconnectAttempts;
|
|
19751
19772
|
this.reconnectAttempts = 0;
|
|
19752
19773
|
this.clearReconnectTimeout();
|
|
19753
19774
|
this.clearConnectionTimeout();
|
|
@@ -19758,6 +19779,14 @@ var __webpack_exports__ = {};
|
|
|
19758
19779
|
const socketError = this.lastSocketError;
|
|
19759
19780
|
const contents = {
|
|
19760
19781
|
cause,
|
|
19782
|
+
transportPhase: void 0 === this.connectionOpenedAt ? "initial" : "idle",
|
|
19783
|
+
mediaTransmissionStarted: this.mediaTransmissionStarted,
|
|
19784
|
+
recordingActive: this.recordingActive,
|
|
19785
|
+
framesCount: this.framesCount,
|
|
19786
|
+
samplesCount: this.samplesCount,
|
|
19787
|
+
reconnectAttempts,
|
|
19788
|
+
connectionOpenedAt: this.connectionOpenedAt,
|
|
19789
|
+
automation: util_getAutomationSignals(),
|
|
19761
19790
|
closeCode: null == closeEvent ? void 0 : closeEvent.code,
|
|
19762
19791
|
closeReason: null == closeEvent ? void 0 : closeEvent.reason,
|
|
19763
19792
|
elapsedMs,
|
|
@@ -19799,7 +19828,7 @@ var __webpack_exports__ = {};
|
|
|
19799
19828
|
});
|
|
19800
19829
|
}
|
|
19801
19830
|
shouldIgnoreConnectionFailure() {
|
|
19802
|
-
return this.connectionFailed || this.connected || Boolean(this.unloaded) || this.validate();
|
|
19831
|
+
return this.connectionFailed || this.connected || Boolean(this.unloaded) || this.validate() || this.blocking && !this.mediaTransmissionStarted;
|
|
19803
19832
|
}
|
|
19804
19833
|
initSocket(cb) {
|
|
19805
19834
|
if (this.connected) {
|
|
@@ -19809,7 +19838,8 @@ var __webpack_exports__ = {};
|
|
|
19809
19838
|
}
|
|
19810
19839
|
if (this.connecting) return void this.options.logger.debug("Recorder: already **connecting**. Not going to initialize a new WebSocket connection.");
|
|
19811
19840
|
this.clearReconnectTimeout();
|
|
19812
|
-
|
|
19841
|
+
const automation = util_getAutomationSignals();
|
|
19842
|
+
if (automation.userAgentMatched) {
|
|
19813
19843
|
this.connecting = false;
|
|
19814
19844
|
this.options.logger.debug("Recorder: skipping web socket connection for an automated crawler");
|
|
19815
19845
|
return;
|
|
@@ -19843,6 +19873,8 @@ var __webpack_exports__ = {};
|
|
|
19843
19873
|
try {
|
|
19844
19874
|
nativeSocket = new WebSocket(url2Connect);
|
|
19845
19875
|
nativeSocket.addEventListener("close", (event)=>{
|
|
19876
|
+
var _this_stream;
|
|
19877
|
+
if ((null == (_this_stream = this.stream) ? void 0 : _this_stream.socket) !== nativeSocket) return;
|
|
19846
19878
|
this.lastCloseEvent = {
|
|
19847
19879
|
code: event.code,
|
|
19848
19880
|
reason: event.reason,
|
|
@@ -19850,6 +19882,8 @@ var __webpack_exports__ = {};
|
|
|
19850
19882
|
};
|
|
19851
19883
|
});
|
|
19852
19884
|
nativeSocket.addEventListener("error", (event)=>{
|
|
19885
|
+
var _this_stream;
|
|
19886
|
+
if ((null == (_this_stream = this.stream) ? void 0 : _this_stream.socket) !== nativeSocket) return;
|
|
19853
19887
|
this.lastSocketError = error_getEventDetails(event);
|
|
19854
19888
|
});
|
|
19855
19889
|
} catch (exc) {
|
|
@@ -19861,7 +19895,10 @@ var __webpack_exports__ = {};
|
|
|
19861
19895
|
message,
|
|
19862
19896
|
explanation,
|
|
19863
19897
|
options: this.options,
|
|
19864
|
-
exc
|
|
19898
|
+
exc,
|
|
19899
|
+
cause: {
|
|
19900
|
+
automation
|
|
19901
|
+
}
|
|
19865
19902
|
});
|
|
19866
19903
|
this.emit("ERROR", {
|
|
19867
19904
|
err
|
|
@@ -19899,15 +19936,16 @@ var __webpack_exports__ = {};
|
|
|
19899
19936
|
});
|
|
19900
19937
|
}, connectionTimeoutMs);
|
|
19901
19938
|
stream.on("close", ()=>{
|
|
19902
|
-
this.handleStreamClose(url2Connect);
|
|
19939
|
+
if (this.stream === stream) this.handleStreamClose(url2Connect);
|
|
19903
19940
|
});
|
|
19904
19941
|
stream.on("connect", (args)=>{
|
|
19905
|
-
|
|
19942
|
+
if (this.stream !== stream) return;
|
|
19906
19943
|
this.options.logger.debug(`${PIPE_SYMBOL}Stream *connect* event emitted with args: ${string_pretty(args)}`);
|
|
19907
19944
|
this.clearConnectionTimeout();
|
|
19908
|
-
const isClosing =
|
|
19945
|
+
const isClosing = stream.socket.readyState === WebSocket.CLOSING;
|
|
19909
19946
|
if (!this.connected && !isClosing && !this.unloaded) {
|
|
19910
19947
|
this.connected = true;
|
|
19948
|
+
this.connectionOpenedAt = Date.now();
|
|
19911
19949
|
this.connecting = this.unloaded = false;
|
|
19912
19950
|
this.reconnecting = false;
|
|
19913
19951
|
this.reconnectAttempts = 0;
|
|
@@ -19917,6 +19955,7 @@ var __webpack_exports__ = {};
|
|
|
19917
19955
|
}
|
|
19918
19956
|
});
|
|
19919
19957
|
stream.on("data", (data)=>{
|
|
19958
|
+
if (this.stream !== stream) return;
|
|
19920
19959
|
this.options.logger.debug(`${PIPE_SYMBOL}Stream *data* event emitted`);
|
|
19921
19960
|
try {
|
|
19922
19961
|
const command = JSON.parse(data.toString());
|
|
@@ -19935,10 +19974,10 @@ var __webpack_exports__ = {};
|
|
|
19935
19974
|
}
|
|
19936
19975
|
});
|
|
19937
19976
|
stream.on("error", (err)=>{
|
|
19938
|
-
this.handleStreamError(url2Connect, err);
|
|
19977
|
+
if (this.stream === stream) this.handleStreamError(url2Connect, err);
|
|
19939
19978
|
});
|
|
19940
19979
|
stream.on("drain", ()=>{
|
|
19941
|
-
this.handleStreamDrain(stream);
|
|
19980
|
+
if (this.stream === stream) this.handleStreamDrain(stream);
|
|
19942
19981
|
});
|
|
19943
19982
|
stream.on("preend", (args)=>{
|
|
19944
19983
|
this.options.logger.debug(`${PIPE_SYMBOL}Stream *preend* event emitted with args: ${string_pretty(args)}`);
|
|
@@ -19992,7 +20031,7 @@ var __webpack_exports__ = {};
|
|
|
19992
20031
|
}
|
|
19993
20032
|
}
|
|
19994
20033
|
constructor(options){
|
|
19995
|
-
super(options), connection_define_property(this, "reconnectTimeout", void 0), connection_define_property(this, "connectionTimeout", void 0), connection_define_property(this, "userMediaLoaded", void 0), connection_define_property(this, "userMediaLoading", false), connection_define_property(this, "unloaded", void 0), connection_define_property(this, "connectionFailed", false), connection_define_property(this, "reconnectAttempts", 0), connection_define_property(this, "blocking", false), connection_define_property(this, "connectingStartedAt", void 0), connection_define_property(this, "lastCloseEvent", void 0), connection_define_property(this, "lastSocketError", void 0), connection_define_property(this, "pingInterval", void 0);
|
|
20034
|
+
super(options), connection_define_property(this, "reconnectTimeout", void 0), connection_define_property(this, "connectionTimeout", void 0), connection_define_property(this, "userMediaLoaded", void 0), connection_define_property(this, "userMediaLoading", false), connection_define_property(this, "unloaded", void 0), connection_define_property(this, "connectionFailed", false), connection_define_property(this, "reconnectAttempts", 0), connection_define_property(this, "blocking", false), connection_define_property(this, "connectingStartedAt", void 0), connection_define_property(this, "lastCloseEvent", void 0), connection_define_property(this, "lastSocketError", void 0), connection_define_property(this, "pingInterval", void 0), connection_define_property(this, "connectionOpenedAt", void 0);
|
|
19996
20035
|
}
|
|
19997
20036
|
}
|
|
19998
20037
|
const connection = RecorderConnection;
|
|
@@ -20055,6 +20094,7 @@ var __webpack_exports__ = {};
|
|
|
20055
20094
|
const characteristics = null == (_this_userMedia = this.userMedia) ? void 0 : _this_userMedia.getCharacteristics();
|
|
20056
20095
|
this.options.logger.debug(`Recorder: userMediaErrorCallback(), name: ${err.name}, message: ${err.message} and Webcam characteristics: ${characteristics ? string_pretty(characteristics) : "none"}`);
|
|
20057
20096
|
const errorListeners = this.getListeners("ERROR");
|
|
20097
|
+
if (err.name !== error_VideomailError.MEDIA_DEVICE_NOT_SUPPORTED) this.closeIdleConnection("camera-access-failed");
|
|
20058
20098
|
if (null == errorListeners ? void 0 : errorListeners.length) if (err.name !== error_VideomailError.MEDIA_DEVICE_NOT_SUPPORTED) {
|
|
20059
20099
|
const videomailError = error_createError({
|
|
20060
20100
|
err,
|
|
@@ -21832,6 +21872,7 @@ var __webpack_exports__ = {};
|
|
|
21832
21872
|
this.cancelCameraRecovery();
|
|
21833
21873
|
this.blocking = true;
|
|
21834
21874
|
this.clearUserMediaTimeout();
|
|
21875
|
+
this.closeIdleConnection("blocking-error");
|
|
21835
21876
|
});
|
|
21836
21877
|
this.on("PREVIEW", ()=>{
|
|
21837
21878
|
this.hide();
|
package/dist/esm/index.js
CHANGED
|
@@ -3620,7 +3620,7 @@ const constants = {
|
|
|
3620
3620
|
}
|
|
3621
3621
|
};
|
|
3622
3622
|
var package_namespaceObject = {
|
|
3623
|
-
rE: "16.
|
|
3623
|
+
rE: "16.7.0"
|
|
3624
3624
|
};
|
|
3625
3625
|
function isAudioEnabled(options) {
|
|
3626
3626
|
return Boolean(options.audio.enabled);
|
|
@@ -6119,6 +6119,18 @@ function summarize(title, contents) {
|
|
|
6119
6119
|
return line;
|
|
6120
6120
|
}
|
|
6121
6121
|
const string_summarize = summarize;
|
|
6122
|
+
function isAutomatedUserAgent(userAgent = navigator.userAgent) {
|
|
6123
|
+
return /bot|crawler|spider|headlesschrome|phantomjs|puppeteer|playwright/iu.test(userAgent);
|
|
6124
|
+
}
|
|
6125
|
+
const util_isAutomatedUserAgent = isAutomatedUserAgent;
|
|
6126
|
+
function getAutomationSignals() {
|
|
6127
|
+
const webdriver = navigator.webdriver;
|
|
6128
|
+
return {
|
|
6129
|
+
webdriver: true === webdriver,
|
|
6130
|
+
userAgentMatched: util_isAutomatedUserAgent()
|
|
6131
|
+
};
|
|
6132
|
+
}
|
|
6133
|
+
const util_getAutomationSignals = getAutomationSignals;
|
|
6122
6134
|
function getEdgeCodes(value, amount, fromEnd) {
|
|
6123
6135
|
const chars = fromEnd ? value.slice(-amount) : value.slice(0, amount);
|
|
6124
6136
|
const codes = Array.from(chars, (char)=>String(char.codePointAt(0))).join(".");
|
|
@@ -6146,15 +6158,16 @@ function getLanguagesValue() {
|
|
|
6146
6158
|
if (languageList.length > 0) return languageList.join(",");
|
|
6147
6159
|
return navigator.language || "none";
|
|
6148
6160
|
}
|
|
6149
|
-
function
|
|
6161
|
+
function getDiagnosticSignals(probeBase, probeSimpleQuery) {
|
|
6150
6162
|
const reasons = [];
|
|
6151
|
-
|
|
6152
|
-
if (
|
|
6163
|
+
const automation = util_getAutomationSignals();
|
|
6164
|
+
if (automation.webdriver) reasons.push("webdriver=true");
|
|
6165
|
+
if (automation.userAgentMatched) reasons.push("headless_ua_marker");
|
|
6153
6166
|
if (0 === navigator.languages.length) reasons.push("no_languages");
|
|
6154
6167
|
if ("ok" !== probeBase) reasons.push("probe_base_failed");
|
|
6155
6168
|
if ("ok" !== probeSimpleQuery) reasons.push("probe_simple_query_failed");
|
|
6156
6169
|
return {
|
|
6157
|
-
looksAutomated:
|
|
6170
|
+
looksAutomated: automation.webdriver || automation.userAgentMatched,
|
|
6158
6171
|
reasons: reasons.length > 0 ? reasons.join(",") : "none"
|
|
6159
6172
|
};
|
|
6160
6173
|
}
|
|
@@ -6171,7 +6184,7 @@ function getWebSocketDiagnostic(url2Connect) {
|
|
|
6171
6184
|
const probeBase = probeWebSocketConstructor("wss://videomail.io");
|
|
6172
6185
|
const probeWithSimpleQuery = probeWebSocketConstructor("wss://videomail.io/?a=b");
|
|
6173
6186
|
const languages = getLanguagesValue();
|
|
6174
|
-
const automationSignals =
|
|
6187
|
+
const automationSignals = getDiagnosticSignals(probeBase, probeWithSimpleQuery);
|
|
6175
6188
|
const diagnosticPairs = [
|
|
6176
6189
|
`webdriver=${String(navigator.webdriver)}`,
|
|
6177
6190
|
`wsCtorNative=${String(wsCtorNative)}`,
|
|
@@ -6198,10 +6211,6 @@ function getWebSocketDiagnostic(url2Connect) {
|
|
|
6198
6211
|
};
|
|
6199
6212
|
}
|
|
6200
6213
|
const error_getWebSocketDiagnostic = getWebSocketDiagnostic;
|
|
6201
|
-
function isAutomatedUserAgent(userAgent = navigator.userAgent) {
|
|
6202
|
-
return /bot|crawler|spider|headlesschrome|phantomjs|puppeteer|playwright/iu.test(userAgent);
|
|
6203
|
-
}
|
|
6204
|
-
const util_isAutomatedUserAgent = isAutomatedUserAgent;
|
|
6205
6214
|
function boundedWriteQueue_define_property(obj, key, value) {
|
|
6206
6215
|
if (key in obj) Object.defineProperty(obj, key, {
|
|
6207
6216
|
value: value,
|
|
@@ -6397,6 +6406,9 @@ class RecorderStreamWriter extends util_Despot {
|
|
|
6397
6406
|
explanation: "The server connection closed before this recording completed. It cannot be safely resumed, so it has been stopped. Please start a new recording.",
|
|
6398
6407
|
options: this.options,
|
|
6399
6408
|
cause: {
|
|
6409
|
+
transportPhase: "recording",
|
|
6410
|
+
mediaTransmissionStarted: true,
|
|
6411
|
+
automation: util_getAutomationSignals(),
|
|
6400
6412
|
unconfirmedFrames,
|
|
6401
6413
|
unconfirmedSamples
|
|
6402
6414
|
}
|
|
@@ -6464,15 +6476,32 @@ class RecorderConnection extends streamWriter {
|
|
|
6464
6476
|
this.resumeAfterDrain = false;
|
|
6465
6477
|
this.reconnecting = true;
|
|
6466
6478
|
this.initSocket();
|
|
6467
|
-
} else if (this.shouldReportStreamClose())
|
|
6468
|
-
this.
|
|
6469
|
-
|
|
6470
|
-
|
|
6471
|
-
|
|
6472
|
-
|
|
6479
|
+
} else if (this.shouldReportStreamClose()) {
|
|
6480
|
+
const stream = this.stream;
|
|
6481
|
+
window.setTimeout(()=>{
|
|
6482
|
+
if (this.stream === stream) this.handleConnectionFailure({
|
|
6483
|
+
url2Connect,
|
|
6484
|
+
cause: "closed"
|
|
6485
|
+
});
|
|
6486
|
+
}, 0);
|
|
6487
|
+
}
|
|
6473
6488
|
}
|
|
6474
6489
|
shouldIgnoreStreamClose() {
|
|
6475
|
-
return this.recordingTransportFailed || Boolean(this.unloaded) || this.validate();
|
|
6490
|
+
return this.recordingTransportFailed || Boolean(this.unloaded) || this.validate() || this.blocking && !this.mediaTransmissionStarted;
|
|
6491
|
+
}
|
|
6492
|
+
closeIdleConnection(reason) {
|
|
6493
|
+
if (this.mediaTransmissionStarted) return;
|
|
6494
|
+
this.options.logger.debug(string_summarize("Recorder: closing idle connection", {
|
|
6495
|
+
reason,
|
|
6496
|
+
connected: this.connected,
|
|
6497
|
+
connecting: this.connecting,
|
|
6498
|
+
visibilityState: document.visibilityState
|
|
6499
|
+
}));
|
|
6500
|
+
this.connected = this.connecting = this.reconnecting = false;
|
|
6501
|
+
this.clearConnectionTimeout();
|
|
6502
|
+
this.clearReconnectTimeout();
|
|
6503
|
+
this.stopPings();
|
|
6504
|
+
this.discardSocket();
|
|
6476
6505
|
}
|
|
6477
6506
|
handleStreamError(url2Connect, err) {
|
|
6478
6507
|
if ("u" > typeof Event && err instanceof Event) this.lastSocketError = error_getEventDetails(err);
|
|
@@ -6481,28 +6510,20 @@ class RecorderConnection extends streamWriter {
|
|
|
6481
6510
|
error: serializeError(err)
|
|
6482
6511
|
});
|
|
6483
6512
|
this.options.logger.debug(debugLine);
|
|
6484
|
-
if (this.
|
|
6513
|
+
if (this.shouldIgnoreStreamClose()) {
|
|
6485
6514
|
this.connected = false;
|
|
6486
6515
|
this.stopPings();
|
|
6487
6516
|
this.discardSocket();
|
|
6488
6517
|
return;
|
|
6489
6518
|
}
|
|
6490
|
-
if (
|
|
6519
|
+
if (this.mediaTransmissionStarted) return void this.failInterruptedRecording();
|
|
6520
|
+
this.reconnecting ||= this.canReconnectAfterStreamClose();
|
|
6521
|
+
this.connected = false;
|
|
6522
|
+
this.stopPings();
|
|
6523
|
+
this.handleConnectionFailure({
|
|
6491
6524
|
url2Connect,
|
|
6492
6525
|
cause: "error"
|
|
6493
6526
|
});
|
|
6494
|
-
const streamError = err instanceof Error ? err : new Error("WebSocket stream emitted an error event", {
|
|
6495
|
-
cause: this.lastSocketError ?? err
|
|
6496
|
-
});
|
|
6497
|
-
if (this.mediaTransmissionStarted) return void this.failInterruptedRecording();
|
|
6498
|
-
this.emit("ERROR", {
|
|
6499
|
-
err: error_createError({
|
|
6500
|
-
message: "WebSocket stream error",
|
|
6501
|
-
explanation: `The WebSocket stream emitted an error event. Details: ${string_pretty(err)}`,
|
|
6502
|
-
options: this.options,
|
|
6503
|
-
exc: streamError
|
|
6504
|
-
})
|
|
6505
|
-
});
|
|
6506
6527
|
}
|
|
6507
6528
|
sendPings() {
|
|
6508
6529
|
this.stopPings();
|
|
@@ -6562,6 +6583,7 @@ class RecorderConnection extends streamWriter {
|
|
|
6562
6583
|
this.connectionFailed = true;
|
|
6563
6584
|
this.connecting = false;
|
|
6564
6585
|
this.reconnecting = false;
|
|
6586
|
+
const reconnectAttempts = this.reconnectAttempts;
|
|
6565
6587
|
this.reconnectAttempts = 0;
|
|
6566
6588
|
this.clearReconnectTimeout();
|
|
6567
6589
|
this.clearConnectionTimeout();
|
|
@@ -6572,6 +6594,14 @@ class RecorderConnection extends streamWriter {
|
|
|
6572
6594
|
const socketError = this.lastSocketError;
|
|
6573
6595
|
const contents = {
|
|
6574
6596
|
cause,
|
|
6597
|
+
transportPhase: void 0 === this.connectionOpenedAt ? "initial" : "idle",
|
|
6598
|
+
mediaTransmissionStarted: this.mediaTransmissionStarted,
|
|
6599
|
+
recordingActive: this.recordingActive,
|
|
6600
|
+
framesCount: this.framesCount,
|
|
6601
|
+
samplesCount: this.samplesCount,
|
|
6602
|
+
reconnectAttempts,
|
|
6603
|
+
connectionOpenedAt: this.connectionOpenedAt,
|
|
6604
|
+
automation: util_getAutomationSignals(),
|
|
6575
6605
|
closeCode: closeEvent?.code,
|
|
6576
6606
|
closeReason: closeEvent?.reason,
|
|
6577
6607
|
elapsedMs,
|
|
@@ -6613,7 +6643,7 @@ class RecorderConnection extends streamWriter {
|
|
|
6613
6643
|
});
|
|
6614
6644
|
}
|
|
6615
6645
|
shouldIgnoreConnectionFailure() {
|
|
6616
|
-
return this.connectionFailed || this.connected || Boolean(this.unloaded) || this.validate();
|
|
6646
|
+
return this.connectionFailed || this.connected || Boolean(this.unloaded) || this.validate() || this.blocking && !this.mediaTransmissionStarted;
|
|
6617
6647
|
}
|
|
6618
6648
|
initSocket(cb) {
|
|
6619
6649
|
if (this.connected) {
|
|
@@ -6623,7 +6653,8 @@ class RecorderConnection extends streamWriter {
|
|
|
6623
6653
|
}
|
|
6624
6654
|
if (this.connecting) return void this.options.logger.debug("Recorder: already **connecting**. Not going to initialize a new WebSocket connection.");
|
|
6625
6655
|
this.clearReconnectTimeout();
|
|
6626
|
-
|
|
6656
|
+
const automation = util_getAutomationSignals();
|
|
6657
|
+
if (automation.userAgentMatched) {
|
|
6627
6658
|
this.connecting = false;
|
|
6628
6659
|
this.options.logger.debug("Recorder: skipping web socket connection for an automated crawler");
|
|
6629
6660
|
return;
|
|
@@ -6657,6 +6688,7 @@ class RecorderConnection extends streamWriter {
|
|
|
6657
6688
|
try {
|
|
6658
6689
|
nativeSocket = new WebSocket(url2Connect);
|
|
6659
6690
|
nativeSocket.addEventListener("close", (event)=>{
|
|
6691
|
+
if (this.stream?.socket !== nativeSocket) return;
|
|
6660
6692
|
this.lastCloseEvent = {
|
|
6661
6693
|
code: event.code,
|
|
6662
6694
|
reason: event.reason,
|
|
@@ -6664,6 +6696,7 @@ class RecorderConnection extends streamWriter {
|
|
|
6664
6696
|
};
|
|
6665
6697
|
});
|
|
6666
6698
|
nativeSocket.addEventListener("error", (event)=>{
|
|
6699
|
+
if (this.stream?.socket !== nativeSocket) return;
|
|
6667
6700
|
this.lastSocketError = error_getEventDetails(event);
|
|
6668
6701
|
});
|
|
6669
6702
|
} catch (exc) {
|
|
@@ -6675,7 +6708,10 @@ class RecorderConnection extends streamWriter {
|
|
|
6675
6708
|
message,
|
|
6676
6709
|
explanation,
|
|
6677
6710
|
options: this.options,
|
|
6678
|
-
exc
|
|
6711
|
+
exc,
|
|
6712
|
+
cause: {
|
|
6713
|
+
automation
|
|
6714
|
+
}
|
|
6679
6715
|
});
|
|
6680
6716
|
this.emit("ERROR", {
|
|
6681
6717
|
err
|
|
@@ -6713,14 +6749,16 @@ class RecorderConnection extends streamWriter {
|
|
|
6713
6749
|
});
|
|
6714
6750
|
}, connectionTimeoutMs);
|
|
6715
6751
|
stream.on("close", ()=>{
|
|
6716
|
-
this.handleStreamClose(url2Connect);
|
|
6752
|
+
if (this.stream === stream) this.handleStreamClose(url2Connect);
|
|
6717
6753
|
});
|
|
6718
6754
|
stream.on("connect", (args)=>{
|
|
6755
|
+
if (this.stream !== stream) return;
|
|
6719
6756
|
this.options.logger.debug(`${PIPE_SYMBOL}Stream *connect* event emitted with args: ${string_pretty(args)}`);
|
|
6720
6757
|
this.clearConnectionTimeout();
|
|
6721
|
-
const isClosing =
|
|
6758
|
+
const isClosing = stream.socket.readyState === WebSocket.CLOSING;
|
|
6722
6759
|
if (!this.connected && !isClosing && !this.unloaded) {
|
|
6723
6760
|
this.connected = true;
|
|
6761
|
+
this.connectionOpenedAt = Date.now();
|
|
6724
6762
|
this.connecting = this.unloaded = false;
|
|
6725
6763
|
this.reconnecting = false;
|
|
6726
6764
|
this.reconnectAttempts = 0;
|
|
@@ -6730,6 +6768,7 @@ class RecorderConnection extends streamWriter {
|
|
|
6730
6768
|
}
|
|
6731
6769
|
});
|
|
6732
6770
|
stream.on("data", (data)=>{
|
|
6771
|
+
if (this.stream !== stream) return;
|
|
6733
6772
|
this.options.logger.debug(`${PIPE_SYMBOL}Stream *data* event emitted`);
|
|
6734
6773
|
try {
|
|
6735
6774
|
const command = JSON.parse(data.toString());
|
|
@@ -6748,10 +6787,10 @@ class RecorderConnection extends streamWriter {
|
|
|
6748
6787
|
}
|
|
6749
6788
|
});
|
|
6750
6789
|
stream.on("error", (err)=>{
|
|
6751
|
-
this.handleStreamError(url2Connect, err);
|
|
6790
|
+
if (this.stream === stream) this.handleStreamError(url2Connect, err);
|
|
6752
6791
|
});
|
|
6753
6792
|
stream.on("drain", ()=>{
|
|
6754
|
-
this.handleStreamDrain(stream);
|
|
6793
|
+
if (this.stream === stream) this.handleStreamDrain(stream);
|
|
6755
6794
|
});
|
|
6756
6795
|
stream.on("preend", (args)=>{
|
|
6757
6796
|
this.options.logger.debug(`${PIPE_SYMBOL}Stream *preend* event emitted with args: ${string_pretty(args)}`);
|
|
@@ -6805,7 +6844,7 @@ class RecorderConnection extends streamWriter {
|
|
|
6805
6844
|
}
|
|
6806
6845
|
}
|
|
6807
6846
|
constructor(options){
|
|
6808
|
-
super(options), connection_define_property(this, "reconnectTimeout", void 0), connection_define_property(this, "connectionTimeout", void 0), connection_define_property(this, "userMediaLoaded", void 0), connection_define_property(this, "userMediaLoading", false), connection_define_property(this, "unloaded", void 0), connection_define_property(this, "connectionFailed", false), connection_define_property(this, "reconnectAttempts", 0), connection_define_property(this, "blocking", false), connection_define_property(this, "connectingStartedAt", void 0), connection_define_property(this, "lastCloseEvent", void 0), connection_define_property(this, "lastSocketError", void 0), connection_define_property(this, "pingInterval", void 0);
|
|
6847
|
+
super(options), connection_define_property(this, "reconnectTimeout", void 0), connection_define_property(this, "connectionTimeout", void 0), connection_define_property(this, "userMediaLoaded", void 0), connection_define_property(this, "userMediaLoading", false), connection_define_property(this, "unloaded", void 0), connection_define_property(this, "connectionFailed", false), connection_define_property(this, "reconnectAttempts", 0), connection_define_property(this, "blocking", false), connection_define_property(this, "connectingStartedAt", void 0), connection_define_property(this, "lastCloseEvent", void 0), connection_define_property(this, "lastSocketError", void 0), connection_define_property(this, "pingInterval", void 0), connection_define_property(this, "connectionOpenedAt", void 0);
|
|
6809
6848
|
}
|
|
6810
6849
|
}
|
|
6811
6850
|
const connection = RecorderConnection;
|
|
@@ -6867,6 +6906,7 @@ class RecorderMedia extends connection {
|
|
|
6867
6906
|
const characteristics = this.userMedia?.getCharacteristics();
|
|
6868
6907
|
this.options.logger.debug(`Recorder: userMediaErrorCallback(), name: ${err.name}, message: ${err.message} and Webcam characteristics: ${characteristics ? string_pretty(characteristics) : "none"}`);
|
|
6869
6908
|
const errorListeners = this.getListeners("ERROR");
|
|
6909
|
+
if (err.name !== error_VideomailError.MEDIA_DEVICE_NOT_SUPPORTED) this.closeIdleConnection("camera-access-failed");
|
|
6870
6910
|
if (errorListeners?.length) if (err.name !== error_VideomailError.MEDIA_DEVICE_NOT_SUPPORTED) {
|
|
6871
6911
|
const videomailError = error_createError({
|
|
6872
6912
|
err,
|
|
@@ -8490,6 +8530,7 @@ class Recorder extends capture {
|
|
|
8490
8530
|
this.cancelCameraRecovery();
|
|
8491
8531
|
this.blocking = true;
|
|
8492
8532
|
this.clearUserMediaTimeout();
|
|
8533
|
+
this.closeIdleConnection("blocking-error");
|
|
8493
8534
|
});
|
|
8494
8535
|
this.on("PREVIEW", ()=>{
|
|
8495
8536
|
this.hide();
|
|
@@ -20,6 +20,7 @@ declare abstract class RecorderConnection extends RecorderStreamWriter {
|
|
|
20
20
|
} | undefined;
|
|
21
21
|
protected lastSocketError?: Record<string, unknown> | undefined;
|
|
22
22
|
protected pingInterval?: number | undefined;
|
|
23
|
+
private connectionOpenedAt?;
|
|
23
24
|
protected abstract executeCommand(command: VideomailCommand): void;
|
|
24
25
|
abstract isUserMediaLoaded(): boolean | undefined;
|
|
25
26
|
abstract validate(): boolean;
|
|
@@ -28,6 +29,7 @@ declare abstract class RecorderConnection extends RecorderStreamWriter {
|
|
|
28
29
|
private shouldReportStreamClose;
|
|
29
30
|
private handleStreamClose;
|
|
30
31
|
private shouldIgnoreStreamClose;
|
|
32
|
+
protected closeIdleConnection(reason: string): void;
|
|
31
33
|
private handleStreamError;
|
|
32
34
|
protected sendPings(): void;
|
|
33
35
|
protected stopPings(): void;
|
package/dist/umd/index.js
CHANGED
|
@@ -7218,7 +7218,7 @@
|
|
|
7218
7218
|
const qs = __webpack_require__("b");
|
|
7219
7219
|
const RequestBase = __webpack_require__("d");
|
|
7220
7220
|
const { isObject, mixin, hasOwn, isSafeKey } = __webpack_require__("Dp");
|
|
7221
|
-
const ResponseBase = __webpack_require__("
|
|
7221
|
+
const ResponseBase = __webpack_require__("e");
|
|
7222
7222
|
const Agent = __webpack_require__("pf");
|
|
7223
7223
|
function noop() {}
|
|
7224
7224
|
module1.exports = function(method, url) {
|
|
@@ -7932,7 +7932,7 @@
|
|
|
7932
7932
|
}, this._responseTimeout);
|
|
7933
7933
|
};
|
|
7934
7934
|
},
|
|
7935
|
-
|
|
7935
|
+
e (module1, __unused_rspack_exports, __webpack_require__) {
|
|
7936
7936
|
"use strict";
|
|
7937
7937
|
const utils = __webpack_require__("Dp");
|
|
7938
7938
|
module1.exports = ResponseBase;
|
|
@@ -10643,7 +10643,7 @@
|
|
|
10643
10643
|
return i[1];
|
|
10644
10644
|
};
|
|
10645
10645
|
},
|
|
10646
|
-
|
|
10646
|
+
RR (module1) {
|
|
10647
10647
|
"use strict";
|
|
10648
10648
|
var stylesInDOM = [];
|
|
10649
10649
|
function getIndexByIdentifier(identifier) {
|
|
@@ -11144,7 +11144,7 @@
|
|
|
11144
11144
|
var client = __webpack_require__("Q");
|
|
11145
11145
|
var client_default = /*#__PURE__*/ __webpack_require__.n(client);
|
|
11146
11146
|
var package_namespaceObject = {
|
|
11147
|
-
rE: "16.
|
|
11147
|
+
rE: "16.7.0"
|
|
11148
11148
|
};
|
|
11149
11149
|
function isAudioEnabled(options) {
|
|
11150
11150
|
return Boolean(options.audio.enabled);
|
|
@@ -15724,7 +15724,7 @@
|
|
|
15724
15724
|
return newOptions;
|
|
15725
15725
|
}
|
|
15726
15726
|
const options_mergeWithDefaultOptions = mergeWithDefaultOptions;
|
|
15727
|
-
var injectStylesIntoStyleTag = __webpack_require__("
|
|
15727
|
+
var injectStylesIntoStyleTag = __webpack_require__("RR");
|
|
15728
15728
|
var injectStylesIntoStyleTag_default = /*#__PURE__*/ __webpack_require__.n(injectStylesIntoStyleTag);
|
|
15729
15729
|
var styleDomAPI = __webpack_require__("Bd");
|
|
15730
15730
|
var styleDomAPI_default = /*#__PURE__*/ __webpack_require__.n(styleDomAPI);
|
|
@@ -19070,6 +19070,18 @@
|
|
|
19070
19070
|
canvas_to_buffer_modern_r.atob = void 0;
|
|
19071
19071
|
var websocket_stream_stream = __webpack_require__("U");
|
|
19072
19072
|
var stream_default = /*#__PURE__*/ __webpack_require__.n(websocket_stream_stream);
|
|
19073
|
+
function isAutomatedUserAgent(userAgent = navigator.userAgent) {
|
|
19074
|
+
return /bot|crawler|spider|headlesschrome|phantomjs|puppeteer|playwright/iu.test(userAgent);
|
|
19075
|
+
}
|
|
19076
|
+
const util_isAutomatedUserAgent = isAutomatedUserAgent;
|
|
19077
|
+
function getAutomationSignals() {
|
|
19078
|
+
const webdriver = navigator.webdriver;
|
|
19079
|
+
return {
|
|
19080
|
+
webdriver: true === webdriver,
|
|
19081
|
+
userAgentMatched: util_isAutomatedUserAgent()
|
|
19082
|
+
};
|
|
19083
|
+
}
|
|
19084
|
+
const util_getAutomationSignals = getAutomationSignals;
|
|
19073
19085
|
function getEdgeCodes(value, amount, fromEnd) {
|
|
19074
19086
|
const chars = fromEnd ? value.slice(-amount) : value.slice(0, amount);
|
|
19075
19087
|
const codes = Array.from(chars, (char)=>String(char.codePointAt(0))).join(".");
|
|
@@ -19097,15 +19109,16 @@
|
|
|
19097
19109
|
if (languageList.length > 0) return languageList.join(",");
|
|
19098
19110
|
return navigator.language || "none";
|
|
19099
19111
|
}
|
|
19100
|
-
function
|
|
19112
|
+
function getDiagnosticSignals(probeBase, probeSimpleQuery) {
|
|
19101
19113
|
const reasons = [];
|
|
19102
|
-
|
|
19103
|
-
if (
|
|
19114
|
+
const automation = util_getAutomationSignals();
|
|
19115
|
+
if (automation.webdriver) reasons.push("webdriver=true");
|
|
19116
|
+
if (automation.userAgentMatched) reasons.push("headless_ua_marker");
|
|
19104
19117
|
if (0 === navigator.languages.length) reasons.push("no_languages");
|
|
19105
19118
|
if ("ok" !== probeBase) reasons.push("probe_base_failed");
|
|
19106
19119
|
if ("ok" !== probeSimpleQuery) reasons.push("probe_simple_query_failed");
|
|
19107
19120
|
return {
|
|
19108
|
-
looksAutomated:
|
|
19121
|
+
looksAutomated: automation.webdriver || automation.userAgentMatched,
|
|
19109
19122
|
reasons: reasons.length > 0 ? reasons.join(",") : "none"
|
|
19110
19123
|
};
|
|
19111
19124
|
}
|
|
@@ -19122,7 +19135,7 @@
|
|
|
19122
19135
|
const probeBase = probeWebSocketConstructor("wss://videomail.io");
|
|
19123
19136
|
const probeWithSimpleQuery = probeWebSocketConstructor("wss://videomail.io/?a=b");
|
|
19124
19137
|
const languages = getLanguagesValue();
|
|
19125
|
-
const automationSignals =
|
|
19138
|
+
const automationSignals = getDiagnosticSignals(probeBase, probeWithSimpleQuery);
|
|
19126
19139
|
const diagnosticPairs = [
|
|
19127
19140
|
`webdriver=${String(navigator.webdriver)}`,
|
|
19128
19141
|
`wsCtorNative=${String(wsCtorNative)}`,
|
|
@@ -19149,10 +19162,6 @@
|
|
|
19149
19162
|
};
|
|
19150
19163
|
}
|
|
19151
19164
|
const error_getWebSocketDiagnostic = getWebSocketDiagnostic;
|
|
19152
|
-
function isAutomatedUserAgent(userAgent = navigator.userAgent) {
|
|
19153
|
-
return /bot|crawler|spider|headlesschrome|phantomjs|puppeteer|playwright/iu.test(userAgent);
|
|
19154
|
-
}
|
|
19155
|
-
const util_isAutomatedUserAgent = isAutomatedUserAgent;
|
|
19156
19165
|
const DEFAULT_MAX_QUEUED_BYTES = 1048576;
|
|
19157
19166
|
class BoundedWriteQueue {
|
|
19158
19167
|
maxBytes;
|
|
@@ -19346,6 +19355,9 @@
|
|
|
19346
19355
|
explanation: "The server connection closed before this recording completed. It cannot be safely resumed, so it has been stopped. Please start a new recording.",
|
|
19347
19356
|
options: this.options,
|
|
19348
19357
|
cause: {
|
|
19358
|
+
transportPhase: "recording",
|
|
19359
|
+
mediaTransmissionStarted: true,
|
|
19360
|
+
automation: util_getAutomationSignals(),
|
|
19349
19361
|
unconfirmedFrames,
|
|
19350
19362
|
unconfirmedSamples
|
|
19351
19363
|
}
|
|
@@ -19387,6 +19399,7 @@
|
|
|
19387
19399
|
lastCloseEvent;
|
|
19388
19400
|
lastSocketError;
|
|
19389
19401
|
pingInterval;
|
|
19402
|
+
connectionOpenedAt;
|
|
19390
19403
|
constructor(options){
|
|
19391
19404
|
super(options);
|
|
19392
19405
|
}
|
|
@@ -19415,15 +19428,32 @@
|
|
|
19415
19428
|
this.resumeAfterDrain = false;
|
|
19416
19429
|
this.reconnecting = true;
|
|
19417
19430
|
this.initSocket();
|
|
19418
|
-
} else if (this.shouldReportStreamClose())
|
|
19419
|
-
this.
|
|
19420
|
-
|
|
19421
|
-
|
|
19422
|
-
|
|
19423
|
-
|
|
19431
|
+
} else if (this.shouldReportStreamClose()) {
|
|
19432
|
+
const stream = this.stream;
|
|
19433
|
+
window.setTimeout(()=>{
|
|
19434
|
+
if (this.stream === stream) this.handleConnectionFailure({
|
|
19435
|
+
url2Connect,
|
|
19436
|
+
cause: "closed"
|
|
19437
|
+
});
|
|
19438
|
+
}, 0);
|
|
19439
|
+
}
|
|
19424
19440
|
}
|
|
19425
19441
|
shouldIgnoreStreamClose() {
|
|
19426
|
-
return this.recordingTransportFailed || Boolean(this.unloaded) || this.validate();
|
|
19442
|
+
return this.recordingTransportFailed || Boolean(this.unloaded) || this.validate() || this.blocking && !this.mediaTransmissionStarted;
|
|
19443
|
+
}
|
|
19444
|
+
closeIdleConnection(reason) {
|
|
19445
|
+
if (this.mediaTransmissionStarted) return;
|
|
19446
|
+
this.options.logger.debug(string_summarize("Recorder: closing idle connection", {
|
|
19447
|
+
reason,
|
|
19448
|
+
connected: this.connected,
|
|
19449
|
+
connecting: this.connecting,
|
|
19450
|
+
visibilityState: document.visibilityState
|
|
19451
|
+
}));
|
|
19452
|
+
this.connected = this.connecting = this.reconnecting = false;
|
|
19453
|
+
this.clearConnectionTimeout();
|
|
19454
|
+
this.clearReconnectTimeout();
|
|
19455
|
+
this.stopPings();
|
|
19456
|
+
this.discardSocket();
|
|
19427
19457
|
}
|
|
19428
19458
|
handleStreamError(url2Connect, err) {
|
|
19429
19459
|
if ("u" > typeof Event && err instanceof Event) this.lastSocketError = error_getEventDetails(err);
|
|
@@ -19432,28 +19462,20 @@
|
|
|
19432
19462
|
error: serializeError(err)
|
|
19433
19463
|
});
|
|
19434
19464
|
this.options.logger.debug(debugLine);
|
|
19435
|
-
if (this.
|
|
19465
|
+
if (this.shouldIgnoreStreamClose()) {
|
|
19436
19466
|
this.connected = false;
|
|
19437
19467
|
this.stopPings();
|
|
19438
19468
|
this.discardSocket();
|
|
19439
19469
|
return;
|
|
19440
19470
|
}
|
|
19441
|
-
if (
|
|
19471
|
+
if (this.mediaTransmissionStarted) return void this.failInterruptedRecording();
|
|
19472
|
+
this.reconnecting ||= this.canReconnectAfterStreamClose();
|
|
19473
|
+
this.connected = false;
|
|
19474
|
+
this.stopPings();
|
|
19475
|
+
this.handleConnectionFailure({
|
|
19442
19476
|
url2Connect,
|
|
19443
19477
|
cause: "error"
|
|
19444
19478
|
});
|
|
19445
|
-
const streamError = err instanceof Error ? err : new Error("WebSocket stream emitted an error event", {
|
|
19446
|
-
cause: this.lastSocketError ?? err
|
|
19447
|
-
});
|
|
19448
|
-
if (this.mediaTransmissionStarted) return void this.failInterruptedRecording();
|
|
19449
|
-
this.emit("ERROR", {
|
|
19450
|
-
err: error_createError({
|
|
19451
|
-
message: "WebSocket stream error",
|
|
19452
|
-
explanation: `The WebSocket stream emitted an error event. Details: ${string_pretty(err)}`,
|
|
19453
|
-
options: this.options,
|
|
19454
|
-
exc: streamError
|
|
19455
|
-
})
|
|
19456
|
-
});
|
|
19457
19479
|
}
|
|
19458
19480
|
sendPings() {
|
|
19459
19481
|
this.stopPings();
|
|
@@ -19513,6 +19535,7 @@
|
|
|
19513
19535
|
this.connectionFailed = true;
|
|
19514
19536
|
this.connecting = false;
|
|
19515
19537
|
this.reconnecting = false;
|
|
19538
|
+
const reconnectAttempts = this.reconnectAttempts;
|
|
19516
19539
|
this.reconnectAttempts = 0;
|
|
19517
19540
|
this.clearReconnectTimeout();
|
|
19518
19541
|
this.clearConnectionTimeout();
|
|
@@ -19523,6 +19546,14 @@
|
|
|
19523
19546
|
const socketError = this.lastSocketError;
|
|
19524
19547
|
const contents = {
|
|
19525
19548
|
cause,
|
|
19549
|
+
transportPhase: void 0 === this.connectionOpenedAt ? "initial" : "idle",
|
|
19550
|
+
mediaTransmissionStarted: this.mediaTransmissionStarted,
|
|
19551
|
+
recordingActive: this.recordingActive,
|
|
19552
|
+
framesCount: this.framesCount,
|
|
19553
|
+
samplesCount: this.samplesCount,
|
|
19554
|
+
reconnectAttempts,
|
|
19555
|
+
connectionOpenedAt: this.connectionOpenedAt,
|
|
19556
|
+
automation: util_getAutomationSignals(),
|
|
19526
19557
|
closeCode: closeEvent?.code,
|
|
19527
19558
|
closeReason: closeEvent?.reason,
|
|
19528
19559
|
elapsedMs,
|
|
@@ -19564,7 +19595,7 @@
|
|
|
19564
19595
|
});
|
|
19565
19596
|
}
|
|
19566
19597
|
shouldIgnoreConnectionFailure() {
|
|
19567
|
-
return this.connectionFailed || this.connected || Boolean(this.unloaded) || this.validate();
|
|
19598
|
+
return this.connectionFailed || this.connected || Boolean(this.unloaded) || this.validate() || this.blocking && !this.mediaTransmissionStarted;
|
|
19568
19599
|
}
|
|
19569
19600
|
initSocket(cb) {
|
|
19570
19601
|
if (this.connected) {
|
|
@@ -19574,7 +19605,8 @@
|
|
|
19574
19605
|
}
|
|
19575
19606
|
if (this.connecting) return void this.options.logger.debug("Recorder: already **connecting**. Not going to initialize a new WebSocket connection.");
|
|
19576
19607
|
this.clearReconnectTimeout();
|
|
19577
|
-
|
|
19608
|
+
const automation = util_getAutomationSignals();
|
|
19609
|
+
if (automation.userAgentMatched) {
|
|
19578
19610
|
this.connecting = false;
|
|
19579
19611
|
this.options.logger.debug("Recorder: skipping web socket connection for an automated crawler");
|
|
19580
19612
|
return;
|
|
@@ -19608,6 +19640,7 @@
|
|
|
19608
19640
|
try {
|
|
19609
19641
|
nativeSocket = new WebSocket(url2Connect);
|
|
19610
19642
|
nativeSocket.addEventListener("close", (event)=>{
|
|
19643
|
+
if (this.stream?.socket !== nativeSocket) return;
|
|
19611
19644
|
this.lastCloseEvent = {
|
|
19612
19645
|
code: event.code,
|
|
19613
19646
|
reason: event.reason,
|
|
@@ -19615,6 +19648,7 @@
|
|
|
19615
19648
|
};
|
|
19616
19649
|
});
|
|
19617
19650
|
nativeSocket.addEventListener("error", (event)=>{
|
|
19651
|
+
if (this.stream?.socket !== nativeSocket) return;
|
|
19618
19652
|
this.lastSocketError = error_getEventDetails(event);
|
|
19619
19653
|
});
|
|
19620
19654
|
} catch (exc) {
|
|
@@ -19626,7 +19660,10 @@
|
|
|
19626
19660
|
message,
|
|
19627
19661
|
explanation,
|
|
19628
19662
|
options: this.options,
|
|
19629
|
-
exc
|
|
19663
|
+
exc,
|
|
19664
|
+
cause: {
|
|
19665
|
+
automation
|
|
19666
|
+
}
|
|
19630
19667
|
});
|
|
19631
19668
|
this.emit("ERROR", {
|
|
19632
19669
|
err
|
|
@@ -19664,14 +19701,16 @@
|
|
|
19664
19701
|
});
|
|
19665
19702
|
}, connectionTimeoutMs);
|
|
19666
19703
|
stream.on("close", ()=>{
|
|
19667
|
-
this.handleStreamClose(url2Connect);
|
|
19704
|
+
if (this.stream === stream) this.handleStreamClose(url2Connect);
|
|
19668
19705
|
});
|
|
19669
19706
|
stream.on("connect", (args)=>{
|
|
19707
|
+
if (this.stream !== stream) return;
|
|
19670
19708
|
this.options.logger.debug(`${PIPE_SYMBOL}Stream *connect* event emitted with args: ${string_pretty(args)}`);
|
|
19671
19709
|
this.clearConnectionTimeout();
|
|
19672
|
-
const isClosing =
|
|
19710
|
+
const isClosing = stream.socket.readyState === WebSocket.CLOSING;
|
|
19673
19711
|
if (!this.connected && !isClosing && !this.unloaded) {
|
|
19674
19712
|
this.connected = true;
|
|
19713
|
+
this.connectionOpenedAt = Date.now();
|
|
19675
19714
|
this.connecting = this.unloaded = false;
|
|
19676
19715
|
this.reconnecting = false;
|
|
19677
19716
|
this.reconnectAttempts = 0;
|
|
@@ -19681,6 +19720,7 @@
|
|
|
19681
19720
|
}
|
|
19682
19721
|
});
|
|
19683
19722
|
stream.on("data", (data)=>{
|
|
19723
|
+
if (this.stream !== stream) return;
|
|
19684
19724
|
this.options.logger.debug(`${PIPE_SYMBOL}Stream *data* event emitted`);
|
|
19685
19725
|
try {
|
|
19686
19726
|
const command = JSON.parse(data.toString());
|
|
@@ -19699,10 +19739,10 @@
|
|
|
19699
19739
|
}
|
|
19700
19740
|
});
|
|
19701
19741
|
stream.on("error", (err)=>{
|
|
19702
|
-
this.handleStreamError(url2Connect, err);
|
|
19742
|
+
if (this.stream === stream) this.handleStreamError(url2Connect, err);
|
|
19703
19743
|
});
|
|
19704
19744
|
stream.on("drain", ()=>{
|
|
19705
|
-
this.handleStreamDrain(stream);
|
|
19745
|
+
if (this.stream === stream) this.handleStreamDrain(stream);
|
|
19706
19746
|
});
|
|
19707
19747
|
stream.on("preend", (args)=>{
|
|
19708
19748
|
this.options.logger.debug(`${PIPE_SYMBOL}Stream *preend* event emitted with args: ${string_pretty(args)}`);
|
|
@@ -19824,6 +19864,7 @@
|
|
|
19824
19864
|
const characteristics = this.userMedia?.getCharacteristics();
|
|
19825
19865
|
this.options.logger.debug(`Recorder: userMediaErrorCallback(), name: ${err.name}, message: ${err.message} and Webcam characteristics: ${characteristics ? string_pretty(characteristics) : "none"}`);
|
|
19826
19866
|
const errorListeners = this.getListeners("ERROR");
|
|
19867
|
+
if (err.name !== error_VideomailError.MEDIA_DEVICE_NOT_SUPPORTED) this.closeIdleConnection("camera-access-failed");
|
|
19827
19868
|
if (errorListeners?.length) if (err.name !== error_VideomailError.MEDIA_DEVICE_NOT_SUPPORTED) {
|
|
19828
19869
|
const videomailError = error_createError({
|
|
19829
19870
|
err,
|
|
@@ -21468,6 +21509,7 @@
|
|
|
21468
21509
|
this.cancelCameraRecovery();
|
|
21469
21510
|
this.blocking = true;
|
|
21470
21511
|
this.clearUserMediaTimeout();
|
|
21512
|
+
this.closeIdleConnection("blocking-error");
|
|
21471
21513
|
});
|
|
21472
21514
|
this.on("PREVIEW", ()=>{
|
|
21473
21515
|
this.hide();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "videomail-client",
|
|
3
|
-
"version": "16.
|
|
3
|
+
"version": "16.7.0",
|
|
4
4
|
"description": "A wicked npm package to record videos directly in the browser, for Deaf and Sign Language!",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"webcam",
|
|
@@ -108,17 +108,17 @@
|
|
|
108
108
|
"eslint-plugin-de-morgan": "2.3.0",
|
|
109
109
|
"eslint-plugin-depend": "1.5.0",
|
|
110
110
|
"eslint-plugin-import-x": "4.17.1",
|
|
111
|
-
"eslint-plugin-package-json": "1.
|
|
112
|
-
"eslint-plugin-regexp": "3.3.
|
|
111
|
+
"eslint-plugin-package-json": "1.13.0",
|
|
112
|
+
"eslint-plugin-regexp": "3.3.3",
|
|
113
113
|
"eslint-plugin-simple-import-sort": "14.0.0",
|
|
114
|
-
"globals": "17.
|
|
114
|
+
"globals": "17.14.0",
|
|
115
115
|
"jsdom": "30.1.3",
|
|
116
116
|
"msw": "3.0.3",
|
|
117
117
|
"msw-storybook-addon": "3.0.3",
|
|
118
118
|
"prettier": "3.9.10",
|
|
119
119
|
"prettier-plugin-curly": "0.4.1",
|
|
120
120
|
"prettier-plugin-jsdoc": "1.8.1",
|
|
121
|
-
"prettier-plugin-packagejson": "3.0
|
|
121
|
+
"prettier-plugin-packagejson": "3.1.0",
|
|
122
122
|
"prettier-plugin-sh": "0.20.2",
|
|
123
123
|
"release-it": "21.1.2",
|
|
124
124
|
"storybook": "10.6.5",
|