@ceeblue/web-utils 2.2.1 → 2.4.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.
@@ -130,6 +130,11 @@ type Params = {
130
130
  * iceServer to use while connecting to a WebRTC stream
131
131
  */
132
132
  iceServer?: RTCIceServer;
133
+ /**
134
+ * Optional media extension (mp4, flv, ts, rts), usefull for protocol like WebRTS which supports different container type.
135
+ * When not set, it's also an output parameter to indicate what is the media type selected
136
+ */
137
+ mediaExt?: string;
133
138
  /**
134
139
  * Optional query to add into the generated url of connection
135
140
  */
@@ -148,6 +153,14 @@ declare enum Type {
148
153
  /**
149
154
  * Some connection utility functions
150
155
  */
156
+ /**
157
+ * Defines the {@link Params.mediaExt} based on the type of parameters and its endpoint.
158
+ * This method always assigns a value to params.mediaExt, defaulting to an empty string if indeterminable,
159
+ * allowing detection of whether the function has been applied to the parameters.
160
+ * @param type The type of parameters to define.
161
+ * @param params The parameters for which the media extension is to be defined
162
+ */
163
+ declare function defineMediaExt(type: Type, params: Params): void;
151
164
  /**
152
165
  * Build an URL from {@link Type | type} and {@link Params | params}
153
166
  * @param type Type of the connection wanted
@@ -161,15 +174,77 @@ type Connect_Params = Params;
161
174
  type Connect_Type = Type;
162
175
  declare const Connect_Type: typeof Type;
163
176
  declare const Connect_buildURL: typeof buildURL;
177
+ declare const Connect_defineMediaExt: typeof defineMediaExt;
164
178
  declare namespace Connect {
165
- export { type Connect_Params as Params, Connect_Type as Type, Connect_buildURL as buildURL };
179
+ export { type Connect_Params as Params, Connect_Type as Type, Connect_buildURL as buildURL, Connect_defineMediaExt as defineMediaExt };
180
+ }
181
+
182
+ /**
183
+ * Copyright 2024 Ceeblue B.V.
184
+ * This file is part of https://github.com/CeeblueTV/web-utils which is released under GNU Affero General Public License.
185
+ * See file LICENSE or go to https://spdx.org/licenses/AGPL-3.0-or-later.html for full license details.
186
+ */
187
+ /**
188
+ * Log types
189
+ */
190
+ declare enum LogType {
191
+ ERROR = "error",
192
+ WARN = "warn",
193
+ INFO = "info",
194
+ DEBUG = "debug"
195
+ }
196
+ /**
197
+ * Log instance
198
+ */
199
+ declare class Log {
200
+ get error(): (...args: any[]) => void;
201
+ get warn(): (...args: any[]) => void;
202
+ get info(): (...args: any[]) => void;
203
+ get debug(): (...args: any[]) => void;
204
+ private _args;
205
+ private _done?;
206
+ private _onLog;
207
+ constructor(onLog: Function, ...args: unknown[]);
208
+ private _bind;
209
+ }
210
+ /**
211
+ * ILog interface used by log methods
212
+ */
213
+ interface ILog {
214
+ /**
215
+ * Build a log
216
+ */
217
+ (...args: unknown[]): Log;
218
+ /**
219
+ * Intercept or redefine any log
220
+ * @param type log level
221
+ * @param args args
222
+ * @returns
223
+ */
224
+ on: (type: LogType, args: unknown[]) => void;
225
+ }
226
+ /**
227
+ * Inherits from this class to use logs
228
+ */
229
+ declare class Loggable {
230
+ /**
231
+ * Start a log
232
+ * @param args
233
+ * @returns a Log object with the levels of log to call
234
+ */
235
+ log: ILog;
166
236
  }
237
+ /**
238
+ * Global log
239
+ */
240
+ declare const log: ILog;
167
241
 
168
242
  /**
169
243
  * Copyright 2024 Ceeblue B.V.
170
244
  * This file is part of https://github.com/CeeblueTV/web-utils which is released under GNU Affero General Public License.
171
245
  * See file LICENSE or go to https://spdx.org/licenses/AGPL-3.0-or-later.html for full license details.
172
246
  */
247
+
173
248
  /**
174
249
  * A advanced EventEmitter which allows to declare event as natural function in the inheriting children class,
175
250
  * function must start by `on` prefix to be recognized as an event.
@@ -211,7 +286,7 @@ declare namespace Connect {
211
286
  * controller.abort();
212
287
  * logger.test(); // displays nothing
213
288
  */
214
- declare class EventEmitter {
289
+ declare class EventEmitter extends Loggable {
215
290
  private _events;
216
291
  /**
217
292
  * Build our EventEmitter, usually call from children class
@@ -266,29 +341,6 @@ declare class FixMap<KeyType, ValueType> {
266
341
  forEach(callbackfn: (value: ValueType, key: KeyType, map: Map<KeyType, ValueType>) => void, thisArg?: any): void;
267
342
  }
268
343
 
269
- /**
270
- * Copyright 2024 Ceeblue B.V.
271
- * This file is part of https://github.com/CeeblueTV/web-utils which is released under GNU Affero General Public License.
272
- * See file LICENSE or go to https://spdx.org/licenses/AGPL-3.0-or-later.html for full license details.
273
- */
274
- /**
275
- * Implement this interface to throw log and error
276
- */
277
- interface ILog {
278
- /**
279
- * Call to distribute log message, default implementation is usually `onLog(log:string) { console.log(log); }`
280
- * @param log log string message
281
- * @event
282
- */
283
- onLog(log: string): void;
284
- /**
285
- * Call to distribute error message, default implementation is usually `onError(error:string) { console.error(error); }`
286
- * @param error error string message
287
- * @event
288
- */
289
- onError(error: string): void;
290
- }
291
-
292
344
  /**
293
345
  * Copyright 2024 Ceeblue B.V.
294
346
  * This file is part of https://github.com/CeeblueTV/web-utils which is released under GNU Affero General Public License.
@@ -668,27 +720,58 @@ declare function equal(a: any, b: any): boolean;
668
720
  */
669
721
  declare function fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
670
722
  /**
671
- * Extension parser
723
+ * Get Extension part from path
672
724
  * @param path path to parse
673
725
  * @returns the extension
674
726
  */
675
- declare function parseExtension(path: string): string;
727
+ declare function getExtension(path: string): string;
728
+ /**
729
+ * Get File part from path
730
+ * @param path path to parse
731
+ * @returns the file name
732
+ */
733
+ declare function getFile(path: string): string;
734
+ /**
735
+ * String Trim function with customizable chars
736
+ * @param value string to trim
737
+ * @param chars chars to use to trim
738
+ * @returns string trimmed
739
+ */
740
+ declare function trim(value: string, chars?: string): string;
741
+ /**
742
+ * String Trim Start function with customizable chars
743
+ * @param value string to trim start
744
+ * @param chars chars to use to trim start
745
+ * @returns string trimmed
746
+ */
747
+ declare function trimStart(value: string, chars?: string): string;
748
+ /**
749
+ * String Trim End function with customizable chars
750
+ * @param value string to trim end
751
+ * @param chars chars to use to trim end
752
+ * @returns string trimmed
753
+ */
754
+ declare function trimEnd(value: string, chars?: string): string;
676
755
 
677
756
  declare const Util_EMPTY_FUNCTION: typeof EMPTY_FUNCTION;
678
757
  declare const Util_equal: typeof equal;
679
758
  declare const Util_fetch: typeof fetch;
759
+ declare const Util_getExtension: typeof getExtension;
760
+ declare const Util_getFile: typeof getFile;
680
761
  declare const Util_objectEntries: typeof objectEntries;
681
762
  declare const Util_objectFrom: typeof objectFrom;
682
763
  declare const Util_options: typeof options;
683
- declare const Util_parseExtension: typeof parseExtension;
684
764
  declare const Util_safePromise: typeof safePromise;
685
765
  declare const Util_sleep: typeof sleep;
686
766
  declare const Util_stringify: typeof stringify;
687
767
  declare const Util_time: typeof time;
688
768
  declare const Util_timeOrigin: typeof timeOrigin;
689
769
  declare const Util_toBin: typeof toBin;
770
+ declare const Util_trim: typeof trim;
771
+ declare const Util_trimEnd: typeof trimEnd;
772
+ declare const Util_trimStart: typeof trimStart;
690
773
  declare namespace Util {
691
- export { Util_EMPTY_FUNCTION as EMPTY_FUNCTION, Util_equal as equal, Util_fetch as fetch, Util_objectEntries as objectEntries, Util_objectFrom as objectFrom, Util_options as options, Util_parseExtension as parseExtension, Util_safePromise as safePromise, Util_sleep as sleep, Util_stringify as stringify, Util_time as time, Util_timeOrigin as timeOrigin, Util_toBin as toBin };
774
+ export { Util_EMPTY_FUNCTION as EMPTY_FUNCTION, Util_equal as equal, Util_fetch as fetch, Util_getExtension as getExtension, Util_getFile as getFile, Util_objectEntries as objectEntries, Util_objectFrom as objectFrom, Util_options as options, Util_safePromise as safePromise, Util_sleep as sleep, Util_stringify as stringify, Util_time as time, Util_timeOrigin as timeOrigin, Util_toBin as toBin, Util_trim as trim, Util_trimEnd as trimEnd, Util_trimStart as trimStart };
692
775
  }
693
776
 
694
777
  /**
@@ -697,6 +780,33 @@ declare namespace Util {
697
780
  * See file LICENSE or go to https://spdx.org/licenses/AGPL-3.0-or-later.html for full license details.
698
781
  */
699
782
 
783
+ type WebSocketReliableError =
784
+ /**
785
+ * Represents a WebSocket disconnection error.
786
+ */
787
+ {
788
+ type: 'WebSocketReliableError';
789
+ name: 'Socket disconnection';
790
+ url: string;
791
+ reason: string;
792
+ }
793
+ /**
794
+ * Represents a server shutdown error.
795
+ */
796
+ | {
797
+ type: 'WebSocketReliableError';
798
+ name: 'Server shutdown';
799
+ url: string;
800
+ }
801
+ /**
802
+ * Represents a connection failure error.
803
+ */
804
+ | {
805
+ type: 'WebSocketReliableError';
806
+ name: 'Connection failed';
807
+ url: string;
808
+ reason: string;
809
+ };
700
810
  /**
701
811
  * The WebSocketReliable class extends WebSocket to bring up the following improvements:
702
812
  * - Fix all possible unintentional closing ways to get always a related error message, {@link onClose | onClose(error?) event}
@@ -737,7 +847,7 @@ declare class WebSocketReliable extends EventEmitter {
737
847
  * @event `close` fired on websocket close
738
848
  * @param error error description on an improper closure
739
849
  */
740
- onClose(error?: string): void;
850
+ onClose(error?: WebSocketReliableError): void;
741
851
  /**
742
852
  * binaryType, fix binary type to arrayBuffer
743
853
  */
@@ -809,8 +919,9 @@ declare class WebSocketReliable extends EventEmitter {
809
919
  /**
810
920
  * Close websocket
811
921
  * @param error the error reason if is not a proper close
922
+ * @param detail detail of the error
812
923
  */
813
- close(error?: string): void;
924
+ close(error?: WebSocketReliableError): void;
814
925
  private _send;
815
926
  }
816
927
 
@@ -822,4 +933,4 @@ declare class WebSocketReliable extends EventEmitter {
822
933
 
823
934
  declare const VERSION: string;
824
935
 
825
- export { BinaryReader, BinaryWriter, BitReader, ByteRate, Connect, EventEmitter, FixMap, type ILog, NetAddress, Numbers, Queue, SDP, Util, VERSION, WebSocketReliable };
936
+ export { BinaryReader, BinaryWriter, BitReader, ByteRate, Connect, EventEmitter, FixMap, type ILog, Log, LogType, Loggable, NetAddress, Numbers, Queue, SDP, Util, VERSION, WebSocketReliable, type WebSocketReliableError, log };
package/dist/web-utils.js CHANGED
@@ -642,15 +642,76 @@ function fetch(input, init) {
642
642
  });
643
643
  }
644
644
  /**
645
- * Extension parser
645
+ * Get Extension part from path
646
646
  * @param path path to parse
647
647
  * @returns the extension
648
648
  */
649
- function parseExtension(path) {
649
+ function getExtension(path) {
650
650
  const dot = path.lastIndexOf('.');
651
651
  const ext = dot >= 0 && dot > path.lastIndexOf('/') ? path.substring(dot) : '';
652
652
  return ext;
653
- }var Util=/*#__PURE__*/Object.freeze({__proto__:null,EMPTY_FUNCTION:EMPTY_FUNCTION,equal:equal,fetch:fetch,objectEntries:objectEntries,objectFrom:objectFrom,options:options,parseExtension:parseExtension,safePromise:safePromise,sleep:sleep,stringify:stringify,time:time,timeOrigin:timeOrigin,toBin:toBin});/**
653
+ }
654
+ /**
655
+ * Get File part from path
656
+ * @param path path to parse
657
+ * @returns the file name
658
+ */
659
+ function getFile(path) {
660
+ return path.substring(path.lastIndexOf('/') + 1);
661
+ }
662
+ function codesFromString(value) {
663
+ const codes = [];
664
+ for (let i = 0; i < value.length; ++i) {
665
+ codes.push(value.charCodeAt(i));
666
+ }
667
+ return codes;
668
+ }
669
+ /**
670
+ * String Trim function with customizable chars
671
+ * @param value string to trim
672
+ * @param chars chars to use to trim
673
+ * @returns string trimmed
674
+ */
675
+ function trim(value, chars = ' ') {
676
+ const codes = codesFromString(chars);
677
+ let start = 0;
678
+ while (start < value.length && codes.includes(value.charCodeAt(start))) {
679
+ ++start;
680
+ }
681
+ let end = value.length;
682
+ while (end > 0 && codes.includes(value.charCodeAt(end - 1))) {
683
+ --end;
684
+ }
685
+ return value.substring(start, end);
686
+ }
687
+ /**
688
+ * String Trim Start function with customizable chars
689
+ * @param value string to trim start
690
+ * @param chars chars to use to trim start
691
+ * @returns string trimmed
692
+ */
693
+ function trimStart(value, chars = ' ') {
694
+ const codes = codesFromString(chars);
695
+ let i = 0;
696
+ while (i < value.length && codes.includes(value.charCodeAt(i))) {
697
+ ++i;
698
+ }
699
+ return value.substring(i);
700
+ }
701
+ /**
702
+ * String Trim End function with customizable chars
703
+ * @param value string to trim end
704
+ * @param chars chars to use to trim end
705
+ * @returns string trimmed
706
+ */
707
+ function trimEnd(value, chars = ' ') {
708
+ const codes = codesFromString(chars);
709
+ let i = value.length;
710
+ while (i > 0 && codes.includes(value.charCodeAt(i - 1))) {
711
+ --i;
712
+ }
713
+ return value.substring(0, i);
714
+ }var Util=/*#__PURE__*/Object.freeze({__proto__:null,EMPTY_FUNCTION:EMPTY_FUNCTION,equal:equal,fetch:fetch,getExtension:getExtension,getFile:getFile,objectEntries:objectEntries,objectFrom:objectFrom,options:options,safePromise:safePromise,sleep:sleep,stringify:stringify,time:time,timeOrigin:timeOrigin,toBin:toBin,trim:trim,trimEnd:trimEnd,trimStart:trimStart});/**
654
715
  * Copyright 2024 Ceeblue B.V.
655
716
  * This file is part of https://github.com/CeeblueTV/web-utils which is released under GNU Affero General Public License.
656
717
  * See file LICENSE or go to https://spdx.org/licenses/AGPL-3.0-or-later.html for full license details.
@@ -831,6 +892,56 @@ var Type;
831
892
  /**
832
893
  * Some connection utility functions
833
894
  */
895
+ /**
896
+ * Defines the {@link Params.mediaExt} based on the type of parameters and its endpoint.
897
+ * This method always assigns a value to params.mediaExt, defaulting to an empty string if indeterminable,
898
+ * allowing detection of whether the function has been applied to the parameters.
899
+ * @param type The type of parameters to define.
900
+ * @param params The parameters for which the media extension is to be defined
901
+ */
902
+ function defineMediaExt(type, params) {
903
+ // Fix mediaExt in removing the possible '.' prefix
904
+ if (params.mediaExt) {
905
+ params.mediaExt = trimStart(params.mediaExt, '.');
906
+ }
907
+ // Compute appropriate mediaExt out parameter
908
+ switch (type) {
909
+ case Type.HESP:
910
+ params.mediaExt = 'mp4';
911
+ break;
912
+ case Type.WEBRTC:
913
+ params.mediaExt = 'rtp';
914
+ break;
915
+ case Type.WRTS: {
916
+ try {
917
+ const url = new URL(params.endPoint);
918
+ const ext = getExtension(getFile(url.pathname));
919
+ // set extension just if not json, json means a manifest file endPoint
920
+ if (ext && ext !== 'json') {
921
+ params.mediaExt = ext;
922
+ }
923
+ }
924
+ catch (_) {
925
+ // not an URL, it's only a host => keep mediaExt unchanged to build the URL
926
+ }
927
+ if (!params.mediaExt) {
928
+ // set to its default rts value => always set for WRTS!
929
+ params.mediaExt = 'rts';
930
+ }
931
+ break;
932
+ }
933
+ case Type.META:
934
+ params.mediaExt = 'js';
935
+ break;
936
+ case Type.DATA:
937
+ params.mediaExt = 'json';
938
+ break;
939
+ default:
940
+ params.mediaExt = ''; // set always a value to know that the parameters have been fixed
941
+ console.warn('Unknown params type ' + type);
942
+ break;
943
+ }
944
+ }
834
945
  /**
835
946
  * Build an URL from {@link Type | type} and {@link Params | params}
836
947
  * @param type Type of the connection wanted
@@ -839,10 +950,8 @@ var Type;
839
950
  * @returns The URL of connection
840
951
  */
841
952
  function buildURL(type, params, protocol = 'wss') {
953
+ defineMediaExt(type, params);
842
954
  const url = new URL(NetAddress.fixProtocol(protocol, params.endPoint));
843
- // Remove possible extension of streamName put sometimes to decide format when multiple choices are possible like with WRTS
844
- const ext = parseExtension(params.streamName);
845
- params.streamName = params.streamName.substring(0, params.streamName.length - ext.length);
846
955
  if (url.pathname.length <= 1) {
847
956
  // build ceeblue path!
848
957
  switch (type) {
@@ -853,7 +962,7 @@ function buildURL(type, params, protocol = 'wss') {
853
962
  url.pathname = '/webrtc/' + params.streamName;
854
963
  break;
855
964
  case Type.WRTS:
856
- url.pathname = '/wrts/' + params.streamName + ext;
965
+ url.pathname = '/wrts/' + params.streamName;
857
966
  break;
858
967
  case Type.META:
859
968
  url.pathname = '/json_' + params.streamName + '.js';
@@ -873,7 +982,88 @@ function buildURL(type, params, protocol = 'wss') {
873
982
  url.searchParams.set(key, params.query[key]);
874
983
  }
875
984
  return url;
876
- }var Connect=/*#__PURE__*/Object.freeze({__proto__:null,get Type(){return Type},buildURL:buildURL});/**
985
+ }var Connect=/*#__PURE__*/Object.freeze({__proto__:null,get Type(){return Type},buildURL:buildURL,defineMediaExt:defineMediaExt});/**
986
+ * Copyright 2024 Ceeblue B.V.
987
+ * This file is part of https://github.com/CeeblueTV/web-utils which is released under GNU Affero General Public License.
988
+ * See file LICENSE or go to https://spdx.org/licenses/AGPL-3.0-or-later.html for full license details.
989
+ */
990
+ let _logging = 0;
991
+ setInterval(() => {
992
+ console.assert(_logging === 0, _logging.toFixed(), 'calls to log was useless');
993
+ }, 10000);
994
+ /**
995
+ * Log types
996
+ */
997
+ var LogType;
998
+ (function (LogType) {
999
+ LogType["ERROR"] = "error";
1000
+ LogType["WARN"] = "warn";
1001
+ LogType["INFO"] = "info";
1002
+ LogType["DEBUG"] = "debug";
1003
+ })(LogType || (LogType = {}));
1004
+ /**
1005
+ * Log instance
1006
+ */
1007
+ class Log {
1008
+ get error() {
1009
+ return this._bind(LogType.ERROR);
1010
+ }
1011
+ get warn() {
1012
+ return this._bind(LogType.WARN);
1013
+ }
1014
+ get info() {
1015
+ return this._bind(LogType.INFO);
1016
+ }
1017
+ get debug() {
1018
+ return this._bind(LogType.DEBUG);
1019
+ }
1020
+ constructor(onLog, ...args) {
1021
+ if (!args.length) {
1022
+ // cannot have 0 args to be called correctly!
1023
+ args.push(undefined);
1024
+ }
1025
+ this._args = args;
1026
+ this._onLog = onLog;
1027
+ ++_logging;
1028
+ }
1029
+ _bind(type) {
1030
+ if (!this._done) {
1031
+ this._done = true;
1032
+ --_logging;
1033
+ }
1034
+ // call the local onLog
1035
+ if (this._onLog) {
1036
+ this._onLog(type, this._args);
1037
+ }
1038
+ // call the global onLog
1039
+ if (this._args.length && log.on) {
1040
+ log.on(type, this._args);
1041
+ }
1042
+ // if not intercepted display the log
1043
+ return this._args.length ? console[type].bind(console, ...this._args) : EMPTY_FUNCTION;
1044
+ }
1045
+ }
1046
+ /**
1047
+ * Inherits from this class to use logs
1048
+ */
1049
+ class Loggable {
1050
+ constructor() {
1051
+ /**
1052
+ * Start a log
1053
+ * @param args
1054
+ * @returns a Log object with the levels of log to call
1055
+ */
1056
+ this.log = ((...args) => {
1057
+ return new Log(this.log.on, ...args);
1058
+ });
1059
+ }
1060
+ }
1061
+ /**
1062
+ * Global log
1063
+ */
1064
+ const log = ((...args) => {
1065
+ return new Log(() => { }, ...args);
1066
+ });/**
877
1067
  * Copyright 2024 Ceeblue B.V.
878
1068
  * This file is part of https://github.com/CeeblueTV/web-utils which is released under GNU Affero General Public License.
879
1069
  * See file LICENSE or go to https://spdx.org/licenses/AGPL-3.0-or-later.html for full license details.
@@ -919,11 +1109,12 @@ function buildURL(type, params, protocol = 'wss') {
919
1109
  * controller.abort();
920
1110
  * logger.test(); // displays nothing
921
1111
  */
922
- class EventEmitter {
1112
+ class EventEmitter extends Loggable {
923
1113
  /**
924
1114
  * Build our EventEmitter, usually call from children class
925
1115
  */
926
1116
  constructor() {
1117
+ super();
927
1118
  this._events = new Map();
928
1119
  // Fill events with events as defined!
929
1120
  let proto = Object.getPrototypeOf(this);
@@ -1524,11 +1715,7 @@ class WebSocketReliable extends EventEmitter {
1524
1715
  * @event `close` fired on websocket close
1525
1716
  * @param error error description on an improper closure
1526
1717
  */
1527
- onClose(error) {
1528
- if (error) {
1529
- console.error(error);
1530
- }
1531
- }
1718
+ onClose(error) { }
1532
1719
  /**
1533
1720
  * binaryType, fix binary type to arrayBuffer
1534
1721
  */
@@ -1627,18 +1814,30 @@ class WebSocketReliable extends EventEmitter {
1627
1814
  // Add details and fix close ways
1628
1815
  ws.onclose = (e) => {
1629
1816
  if (!this._opened) {
1630
- // close during connection
1631
- // the caller can differentiate this case of one server shutdown by looking if onOpen was op
1632
- this.close(url.toString() + ' connection failed, ' + String(e.reason || e.code));
1817
+ // close during connection!
1818
+ this.close({
1819
+ type: 'WebSocketReliableError',
1820
+ name: 'Connection failed',
1821
+ url: url.toString(),
1822
+ reason: String(e.reason || e.code)
1823
+ });
1633
1824
  }
1634
1825
  else if (e.code === 1000 || e.code === 1005) {
1635
- // normal disconnection from server, no error to indicate that a reconnection is possible!
1636
- // the caller can differentiate this case of one explicit websocket.close() call in the encpasulating class
1637
- this.close(url.toString() + ' shutdown');
1826
+ // normal disconnection from server
1827
+ this.close({
1828
+ type: 'WebSocketReliableError',
1829
+ name: 'Server shutdown',
1830
+ url: url.toString()
1831
+ });
1638
1832
  }
1639
1833
  else {
1640
1834
  // abnormal disconnection from server
1641
- this.close(url.toString() + ' disconnection, ' + String(e.reason || e.code));
1835
+ this.close({
1836
+ type: 'WebSocketReliableError',
1837
+ name: 'Socket disconnection',
1838
+ url: url.toString(),
1839
+ reason: String(e.reason || e.code)
1840
+ });
1642
1841
  }
1643
1842
  };
1644
1843
  // Wrap send method to queue messages until connection is established.
@@ -1683,6 +1882,7 @@ class WebSocketReliable extends EventEmitter {
1683
1882
  /**
1684
1883
  * Close websocket
1685
1884
  * @param error the error reason if is not a proper close
1885
+ * @param detail detail of the error
1686
1886
  */
1687
1887
  close(error) {
1688
1888
  if (!this._ws || this._closed) {
@@ -1694,9 +1894,11 @@ class WebSocketReliable extends EventEmitter {
1694
1894
  // release resources!
1695
1895
  this._queueing.length = 0;
1696
1896
  this._queueingBytes = 0;
1897
+ if (error) {
1898
+ this.log(error).error();
1899
+ }
1697
1900
  this.onClose(error);
1698
1901
  // Reset _opened in last to allow to differenciate in onClose an error while connecting OR while connected
1699
- // Is welcome to attempt a reconnection when no error OR when error on connection!
1700
1902
  this._opened = false;
1701
1903
  }
1702
1904
  _send(message) {
@@ -1711,4 +1913,4 @@ class WebSocketReliable extends EventEmitter {
1711
1913
  * This file is part of https://github.com/CeeblueTV/web-utils which is released under GNU Affero General Public License.
1712
1914
  * See file LICENSE or go to https://spdx.org/licenses/AGPL-3.0-or-later.html for full license details.
1713
1915
  */
1714
- const VERSION = '2.2.1';export{BinaryReader,BinaryWriter,BitReader,ByteRate,Connect,EventEmitter,FixMap,NetAddress,Numbers,Queue,SDP,Util,VERSION,WebSocketReliable};//# sourceMappingURL=web-utils.js.map
1916
+ const VERSION = '2.4.0';export{BinaryReader,BinaryWriter,BitReader,ByteRate,Connect,EventEmitter,FixMap,Log,LogType,Loggable,NetAddress,Numbers,Queue,SDP,Util,VERSION,WebSocketReliable,log};//# sourceMappingURL=web-utils.js.map