@ceeblue/web-utils 6.0.0 → 7.0.1
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/web-utils.d.ts +20 -7
- package/dist/web-utils.js +131 -45
- package/dist/web-utils.js.map +1 -1
- package/dist/web-utils.min.js +1 -1
- package/dist/web-utils.min.js.map +1 -1
- package/package.json +1 -1
package/dist/web-utils.d.ts
CHANGED
|
@@ -322,7 +322,7 @@ type Params = {
|
|
|
322
322
|
* If `endPoint` is a complete URL and `streamName` is not provided, {@link buildURL} will set this parameter automatically
|
|
323
323
|
* using the second part of the URL's path (the first part being the protocol name), or the first path if no other part exists.
|
|
324
324
|
*/
|
|
325
|
-
streamName
|
|
325
|
+
streamName?: string;
|
|
326
326
|
/**
|
|
327
327
|
* Optional access token to use to join a private stream
|
|
328
328
|
*/
|
|
@@ -891,14 +891,26 @@ declare function safePromise<T>(timeout: number, promise: Promise<T>): Promise<u
|
|
|
891
891
|
*/
|
|
892
892
|
declare function sleep(ms: number): Promise<unknown>;
|
|
893
893
|
/**
|
|
894
|
-
* Test equality between two value whatever their type, array included
|
|
894
|
+
* Test equality between two value whatever their type, object and array included
|
|
895
895
|
*/
|
|
896
|
-
declare function equal(a: any, b: any): boolean;
|
|
896
|
+
declare function equal(a: any, b: any, seen?: WeakMap<WeakKey, any>): boolean;
|
|
897
897
|
/**
|
|
898
|
-
*
|
|
899
|
-
* - throw an string exception if response code is not 200 with the text of the response or uses statusText
|
|
898
|
+
* Fetch help method adding an explicit error property when Response is NOK, with the more accurate textual error inside
|
|
900
899
|
*/
|
|
901
|
-
declare function fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response
|
|
900
|
+
declare function fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response & {
|
|
901
|
+
error?: string;
|
|
902
|
+
}>;
|
|
903
|
+
/**
|
|
904
|
+
* Fetch help method adding an explicit error property when Response is NOK, with the more accurate textual error inside
|
|
905
|
+
* Also measure the rtt of fetching and returns it in the property Response.rtt (guaranteed to be ≥ 1),
|
|
906
|
+
* supports subtracting server processing time using either the Response-Delay or CMSD-rd header when available
|
|
907
|
+
*
|
|
908
|
+
* WIP => replace the current implementation to use Resource Timing API
|
|
909
|
+
*/
|
|
910
|
+
declare function fetchWithRTT(input: RequestInfo | URL, init?: RequestInit): Promise<Response & {
|
|
911
|
+
rtt: number;
|
|
912
|
+
error?: string;
|
|
913
|
+
}>;
|
|
902
914
|
/**
|
|
903
915
|
* Get Extension part from path
|
|
904
916
|
* @param path path to parse
|
|
@@ -942,6 +954,7 @@ declare function trimEnd(value: string, chars?: string): string;
|
|
|
942
954
|
declare const Util_EMPTY_FUNCTION: typeof EMPTY_FUNCTION;
|
|
943
955
|
declare const Util_equal: typeof equal;
|
|
944
956
|
declare const Util_fetch: typeof fetch;
|
|
957
|
+
declare const Util_fetchWithRTT: typeof fetchWithRTT;
|
|
945
958
|
declare const Util_getBaseFile: typeof getBaseFile;
|
|
946
959
|
declare const Util_getExtension: typeof getExtension;
|
|
947
960
|
declare const Util_getFile: typeof getFile;
|
|
@@ -958,7 +971,7 @@ declare const Util_trimEnd: typeof trimEnd;
|
|
|
958
971
|
declare const Util_trimStart: typeof trimStart;
|
|
959
972
|
declare const Util_unixTime: typeof unixTime;
|
|
960
973
|
declare namespace Util {
|
|
961
|
-
export { Util_EMPTY_FUNCTION as EMPTY_FUNCTION, Util_equal as equal, Util_fetch as fetch, Util_getBaseFile as getBaseFile, Util_getExtension as getExtension, Util_getFile as getFile, Util_iterableEntries as iterableEntries, 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_toBin as toBin, Util_trim as trim, Util_trimEnd as trimEnd, Util_trimStart as trimStart, Util_unixTime as unixTime };
|
|
974
|
+
export { Util_EMPTY_FUNCTION as EMPTY_FUNCTION, Util_equal as equal, Util_fetch as fetch, Util_fetchWithRTT as fetchWithRTT, Util_getBaseFile as getBaseFile, Util_getExtension as getExtension, Util_getFile as getFile, Util_iterableEntries as iterableEntries, 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_toBin as toBin, Util_trim as trim, Util_trimEnd as trimEnd, Util_trimStart as trimStart, Util_unixTime as unixTime };
|
|
962
975
|
}
|
|
963
976
|
|
|
964
977
|
/**
|
package/dist/web-utils.js
CHANGED
|
@@ -371,55 +371,141 @@ function safePromise(timeout, promise) {
|
|
|
371
371
|
* Wait in milliseconds, requires a call with await keyword!
|
|
372
372
|
*/
|
|
373
373
|
function sleep(ms) {
|
|
374
|
-
return
|
|
375
|
-
|
|
374
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
375
|
+
return new Promise(resolve => {
|
|
376
|
+
setTimeout(resolve, ms);
|
|
377
|
+
});
|
|
376
378
|
});
|
|
377
379
|
}
|
|
378
380
|
/**
|
|
379
|
-
* Test equality between two value whatever their type, array included
|
|
381
|
+
* Test equality between two value whatever their type, object and array included
|
|
380
382
|
*/
|
|
381
|
-
function equal(a, b) {
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
}
|
|
386
|
-
// both primitive (null and undefined included)
|
|
387
|
-
return a === b;
|
|
383
|
+
function equal(a, b, seen = new WeakMap()) {
|
|
384
|
+
// 1. Check primitve identiy or NaN
|
|
385
|
+
if (a === b) {
|
|
386
|
+
return true;
|
|
388
387
|
}
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
388
|
+
if (Number.isNaN(a) && Number.isNaN(b)) {
|
|
389
|
+
return true;
|
|
390
|
+
}
|
|
391
|
+
// 2. Check the both are complexe object
|
|
392
|
+
if (Object(a) !== a || Object(b) !== b) {
|
|
393
|
+
return false;
|
|
394
|
+
}
|
|
395
|
+
// 3. Catch circular reference
|
|
396
|
+
if (seen.has(a)) {
|
|
397
|
+
return seen.get(a) === b;
|
|
398
|
+
}
|
|
399
|
+
seen.set(a, b);
|
|
400
|
+
// 4. Check « toStringTag » (Date, RegExp, Map, Set…)
|
|
401
|
+
const tagA = Object.prototype.toString.call(a);
|
|
402
|
+
if (tagA !== Object.prototype.toString.call(b)) {
|
|
403
|
+
return false;
|
|
404
|
+
}
|
|
405
|
+
// 5. Special Case
|
|
406
|
+
switch (tagA) {
|
|
407
|
+
case '[object Date]':
|
|
408
|
+
return a.getTime() === b.getTime();
|
|
409
|
+
case '[object RegExp]':
|
|
410
|
+
return a.source === b.source && a.flags === b.flags;
|
|
411
|
+
case '[object Set]':
|
|
412
|
+
case '[object Map]': {
|
|
413
|
+
if (a.size !== b.size) {
|
|
414
|
+
return false;
|
|
415
|
+
}
|
|
416
|
+
const aKeys = a.keys();
|
|
417
|
+
const bKeys = a.keys();
|
|
418
|
+
const aValues = a.values();
|
|
419
|
+
const bValues = b.values();
|
|
420
|
+
let aKey;
|
|
421
|
+
while (!(aKey = aKeys.next()).done) {
|
|
422
|
+
if (!equal(aKey.value, bKeys.next().value)) {
|
|
423
|
+
return false;
|
|
424
|
+
}
|
|
425
|
+
const aValue = aValues.next().value;
|
|
426
|
+
const bValue = bValues.next().value;
|
|
427
|
+
if (aValue !== aKey && !equal(aValue, bValue)) {
|
|
428
|
+
return false;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
return true;
|
|
393
432
|
}
|
|
394
|
-
|
|
433
|
+
}
|
|
434
|
+
// 6. Arrays
|
|
435
|
+
if (Array.isArray(a)) {
|
|
436
|
+
if (!Array.isArray(b) || a.length !== b.length) {
|
|
395
437
|
return false;
|
|
396
438
|
}
|
|
397
|
-
for (let i = 0; i
|
|
398
|
-
if (a[i]
|
|
439
|
+
for (let i = 0; i < a.length; i++) {
|
|
440
|
+
if (!equal(a[i], b[i], seen)) {
|
|
399
441
|
return false;
|
|
400
442
|
}
|
|
401
443
|
}
|
|
402
444
|
return true;
|
|
403
445
|
}
|
|
404
|
-
|
|
446
|
+
// 7. Generic object : keys + symbols
|
|
447
|
+
const keysA = [...Object.keys(a), ...Object.getOwnPropertySymbols(a)];
|
|
448
|
+
if (keysA.length !== Object.keys(b).length + Object.getOwnPropertySymbols(b).length) {
|
|
449
|
+
return false;
|
|
450
|
+
}
|
|
451
|
+
for (const key of keysA) {
|
|
452
|
+
if (!equal(a[key], b[key], seen)) {
|
|
453
|
+
return false;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
return true;
|
|
405
457
|
}
|
|
406
458
|
/**
|
|
407
|
-
*
|
|
408
|
-
* - throw an string exception if response code is not 200 with the text of the response or uses statusText
|
|
459
|
+
* Fetch help method adding an explicit error property when Response is NOK, with the more accurate textual error inside
|
|
409
460
|
*/
|
|
410
461
|
function fetch(input, init) {
|
|
411
462
|
return __awaiter(this, void 0, void 0, function* () {
|
|
412
|
-
const response = yield self.fetch(input, init);
|
|
413
|
-
if (response.
|
|
414
|
-
let error;
|
|
463
|
+
const response = (yield self.fetch(input, init));
|
|
464
|
+
if (!response.ok) {
|
|
415
465
|
if (response.body) {
|
|
416
|
-
error = yield response.text();
|
|
466
|
+
response.error = yield response.text();
|
|
467
|
+
}
|
|
468
|
+
if (!response.error) {
|
|
469
|
+
response.error = response.statusText || response.status.toString() || 'Unknown error';
|
|
417
470
|
}
|
|
418
|
-
throw (error || response.statusText || response.status).toString();
|
|
419
471
|
}
|
|
420
472
|
return response;
|
|
421
473
|
});
|
|
422
474
|
}
|
|
475
|
+
/**
|
|
476
|
+
* Fetch help method adding an explicit error property when Response is NOK, with the more accurate textual error inside
|
|
477
|
+
* Also measure the rtt of fetching and returns it in the property Response.rtt (guaranteed to be ≥ 1),
|
|
478
|
+
* supports subtracting server processing time using either the Response-Delay or CMSD-rd header when available
|
|
479
|
+
*
|
|
480
|
+
* WIP => replace the current implementation to use Resource Timing API
|
|
481
|
+
*/
|
|
482
|
+
function fetchWithRTT(input, init) {
|
|
483
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
484
|
+
// A first OPTIONS request to establish a connection (keep-alive)
|
|
485
|
+
yield fetch(input, Object.assign(Object.assign({}, init), { method: 'OPTIONS' }));
|
|
486
|
+
// Actual RTT measurement
|
|
487
|
+
const startTime = time();
|
|
488
|
+
const response = (yield fetch(input, init));
|
|
489
|
+
response.rtt = time() - startTime;
|
|
490
|
+
// remove the ResponseDelay if indicated by the server
|
|
491
|
+
let responseDelay = Number(response.headers.get('Response-Delay')) || 0;
|
|
492
|
+
if (!responseDelay) {
|
|
493
|
+
// search if we have a CMSD info?
|
|
494
|
+
// cmsd-dynamic "fly";rd=1
|
|
495
|
+
const cmsd = response.headers.get('cmsd-dynamic');
|
|
496
|
+
if (cmsd) {
|
|
497
|
+
for (const param of cmsd.split(';')) {
|
|
498
|
+
const [name, value] = param.split('=');
|
|
499
|
+
if (name.trim().toLowerCase() === 'rd') {
|
|
500
|
+
responseDelay = Number(value) || responseDelay;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
response.rtt = Math.max(1, response.rtt - responseDelay);
|
|
506
|
+
return response;
|
|
507
|
+
});
|
|
508
|
+
}
|
|
423
509
|
/**
|
|
424
510
|
* Get Extension part from path
|
|
425
511
|
* @param path path to parse
|
|
@@ -500,7 +586,7 @@ function trimEnd(value, chars = ' ') {
|
|
|
500
586
|
--i;
|
|
501
587
|
}
|
|
502
588
|
return value.substring(0, i);
|
|
503
|
-
}var Util=/*#__PURE__*/Object.freeze({__proto__:null,EMPTY_FUNCTION:EMPTY_FUNCTION,equal:equal,fetch:fetch,getBaseFile:getBaseFile,getExtension:getExtension,getFile:getFile,iterableEntries:iterableEntries,objectFrom:objectFrom,options:options,safePromise:safePromise,sleep:sleep,stringify:stringify,time:time,toBin:toBin,trim:trim,trimEnd:trimEnd,trimStart:trimStart,unixTime:unixTime});/**
|
|
589
|
+
}var Util=/*#__PURE__*/Object.freeze({__proto__:null,EMPTY_FUNCTION:EMPTY_FUNCTION,equal:equal,fetch:fetch,fetchWithRTT:fetchWithRTT,getBaseFile:getBaseFile,getExtension:getExtension,getFile:getFile,iterableEntries:iterableEntries,objectFrom:objectFrom,options:options,safePromise:safePromise,sleep:sleep,stringify:stringify,time:time,toBin:toBin,trim:trim,trimEnd:trimEnd,trimStart:trimStart,unixTime:unixTime});/**
|
|
504
590
|
* Copyright 2024 Ceeblue B.V.
|
|
505
591
|
* This file is part of https://github.com/CeeblueTV/web-utils which is released under GNU Affero General Public License.
|
|
506
592
|
* See file LICENSE or go to https://spdx.org/licenses/AGPL-3.0-or-later.html for full license details.
|
|
@@ -1167,7 +1253,21 @@ var Type;
|
|
|
1167
1253
|
* @param params The parameters for which the media extension is to be defined
|
|
1168
1254
|
*/
|
|
1169
1255
|
function defineMediaExt(type, params) {
|
|
1256
|
+
var _a;
|
|
1170
1257
|
// Compute appropriate mediaExt out parameter
|
|
1258
|
+
if (!params.mediaExt) {
|
|
1259
|
+
try {
|
|
1260
|
+
const url = new URL(params.endPoint);
|
|
1261
|
+
// Set mediaExt with ?ext= param when set OR url extension
|
|
1262
|
+
params.mediaExt = (_a = url.searchParams.get('ext')) !== null && _a !== void 0 ? _a : getExtension(getFile(url.pathname));
|
|
1263
|
+
}
|
|
1264
|
+
catch (_) {
|
|
1265
|
+
// not an URL, it's only a host
|
|
1266
|
+
params.mediaExt = '';
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
// Normalize mediaExt in removing the possible '.' prefix and change it to lower case
|
|
1270
|
+
params.mediaExt = trimStart(params.mediaExt, '.').toLowerCase();
|
|
1171
1271
|
switch (type) {
|
|
1172
1272
|
case Type.HESP:
|
|
1173
1273
|
params.mediaExt = 'mp4';
|
|
@@ -1176,19 +1276,8 @@ function defineMediaExt(type, params) {
|
|
|
1176
1276
|
params.mediaExt = 'rtp';
|
|
1177
1277
|
break;
|
|
1178
1278
|
case Type.WRTS: {
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
const ext = getExtension(getFile(url.pathname));
|
|
1182
|
-
// set extension just if not json, json means a manifest file endPoint
|
|
1183
|
-
if (ext && ext.toLowerCase() !== '.json') {
|
|
1184
|
-
params.mediaExt = ext;
|
|
1185
|
-
}
|
|
1186
|
-
}
|
|
1187
|
-
catch (_) {
|
|
1188
|
-
// not an URL, it's only a host => keep mediaExt unchanged to build the URL
|
|
1189
|
-
}
|
|
1190
|
-
if (!params.mediaExt) {
|
|
1191
|
-
// set to its default rts value => always set for WRTS!
|
|
1279
|
+
// json means a manifest file endPoint, replace with default rts media extension
|
|
1280
|
+
if (!params.mediaExt || params.mediaExt === 'json') {
|
|
1192
1281
|
params.mediaExt = 'rts';
|
|
1193
1282
|
}
|
|
1194
1283
|
break;
|
|
@@ -1200,12 +1289,9 @@ function defineMediaExt(type, params) {
|
|
|
1200
1289
|
params.mediaExt = 'json';
|
|
1201
1290
|
break;
|
|
1202
1291
|
default:
|
|
1203
|
-
params
|
|
1204
|
-
console.warn('Unknown params type ' + type);
|
|
1292
|
+
log('Unknown params type ' + type).warn();
|
|
1205
1293
|
break;
|
|
1206
1294
|
}
|
|
1207
|
-
// Fix mediaExt in removing the possible '.' prefix
|
|
1208
|
-
params.mediaExt = trimStart(params.mediaExt, '.');
|
|
1209
1295
|
}
|
|
1210
1296
|
/**
|
|
1211
1297
|
* Build an URL from {@link Type | type} and {@link Params | params}
|
|
@@ -1238,7 +1324,7 @@ function buildURL(type, params, protocol = 'wss') {
|
|
|
1238
1324
|
url.pathname = '/' + params.streamName + '.json';
|
|
1239
1325
|
break;
|
|
1240
1326
|
default:
|
|
1241
|
-
|
|
1327
|
+
log('Unknown url type ' + type).warn();
|
|
1242
1328
|
break;
|
|
1243
1329
|
}
|
|
1244
1330
|
}
|
|
@@ -2462,4 +2548,4 @@ class UIMetrics {
|
|
|
2462
2548
|
* This file is part of https://github.com/CeeblueTV/web-utils which is released under GNU Affero General Public License.
|
|
2463
2549
|
* See file LICENSE or go to https://spdx.org/licenses/AGPL-3.0-or-later.html for full license details.
|
|
2464
2550
|
*/
|
|
2465
|
-
const VERSION = '
|
|
2551
|
+
const VERSION = '7.0.1';export{BinaryReader,BinaryWriter,BitReader,ByteRate,Connect,EpochTime,EventEmitter,FixMap,Log,LogLevel,Loggable,NetAddress,Numbers,Queue,SDP,UIMetrics,Util,VERSION,WebSocketReliable,log};//# sourceMappingURL=web-utils.js.map
|