rx-player 3.32.2-dev.2023102600 → 3.32.2-dev.2023110700

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.
Files changed (33) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/VERSION +1 -1
  3. package/dist/_esm5.processed/core/adaptive/adaptive_representation_selector.js +7 -7
  4. package/dist/_esm5.processed/core/adaptive/utils/filter_by_width.js +1 -3
  5. package/dist/_esm5.processed/core/api/public_api.js +2 -2
  6. package/dist/_esm5.processed/core/api/tracks_management/track_choice_manager.js +2 -2
  7. package/dist/_esm5.processed/core/segment_buffers/inventory/segment_inventory.js +10 -11
  8. package/dist/_esm5.processed/parsers/manifest/smooth/create_parser.js +1 -2
  9. package/dist/_esm5.processed/transports/dash/image_pipelines.js +2 -2
  10. package/dist/_esm5.processed/transports/dash/segment_parser.js +2 -3
  11. package/dist/_esm5.processed/transports/dash/text_parser.js +2 -2
  12. package/dist/_esm5.processed/transports/local/segment_parser.js +2 -3
  13. package/dist/_esm5.processed/transports/local/text_parser.js +4 -3
  14. package/dist/rx-player.js +28 -82
  15. package/dist/rx-player.min.js +1 -1
  16. package/package.json +1 -1
  17. package/sonar-project.properties +1 -1
  18. package/src/compat/README.md +18 -12
  19. package/src/core/adaptive/adaptive_representation_selector.ts +8 -18
  20. package/src/core/adaptive/utils/filter_by_width.ts +1 -3
  21. package/src/core/api/public_api.ts +2 -2
  22. package/src/core/api/tracks_management/track_choice_manager.ts +1 -3
  23. package/src/core/segment_buffers/inventory/segment_inventory.ts +7 -14
  24. package/src/parsers/manifest/smooth/create_parser.ts +1 -2
  25. package/src/transports/dash/image_pipelines.ts +1 -2
  26. package/src/transports/dash/segment_parser.ts +1 -2
  27. package/src/transports/dash/text_parser.ts +1 -2
  28. package/src/transports/local/segment_parser.ts +1 -2
  29. package/src/transports/local/text_parser.ts +2 -3
  30. package/dist/_esm5.processed/utils/take_first_set.d.ts +0 -25
  31. package/dist/_esm5.processed/utils/take_first_set.js +0 -32
  32. package/src/utils/__tests__/take_first_set.test.ts +0 -38
  33. package/src/utils/take_first_set.ts +0 -53
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "rx-player",
3
3
  "author": "Canal+",
4
- "version": "3.32.2-dev.2023102600",
4
+ "version": "3.32.2-dev.2023110700",
5
5
  "description": "Canal+ HTML5 Video Player",
6
6
  "main": "./dist/rx-player.js",
7
7
  "keywords": [
@@ -1,7 +1,7 @@
1
1
  sonar.projectKey=rx-player
2
2
  sonar.organization=rx-player
3
3
  sonar.projectName=rx-player
4
- sonar.projectVersion=3.32.2-dev.2023102600
4
+ sonar.projectVersion=3.32.2-dev.2023110700
5
5
  sonar.sources=./src,./demo,./tests
6
6
  sonar.exclusions=demo/full/bundle.js,demo/standalone/lib.js,demo/bundle.js
7
7
  sonar.host.url=https://sonarcloud.io
@@ -1,23 +1,29 @@
1
1
  # Compatibility files ##########################################################
2
2
 
3
- Those are "Compat" files, which concentrates any compatibility-related logic.
3
+ Those are "Compat" files, which regroups any compatibility-related logic.
4
4
 
5
5
  All those files try to make the RxPlayer work the exact same way on different
6
- browsers and environments (desktop, set-top boxes, ChromeCast, smart TVs...)
7
- as those may have some differences between one another.
8
-
9
- The files exported here are mostly organized as one file per function and are
10
- all exported through the `index.ts` file.
6
+ browsers and environments (desktop, set-top boxes, ChromeCast, smart TVs, game
7
+ consoles...) as those may have some differences between one another, most often
8
+ due to platform-specific issues.
11
9
 
12
10
  Any logic which is just about implementing work-arounds for specific browsers
13
- or environments (because the do not follow the specifications nor the most
14
- popular implementation of a feature) should be put there.
15
- This way, those can be easily checked and updated (for example when a new
16
- browser version fixing the issue come, or when another browser is found to have
17
- the same one) at any time.
11
+ or environments (because they do not follow the specifications or the most
12
+ popular implementation of a feature) should be put there. This logic can be
13
+ either the implementation itself or just be the conditions to trigger those
14
+ work-arounds, on a case-by-case basis depending on what's more maintainable.
15
+
16
+ By having a single directory for compatibility work-arounds, we make those
17
+ specific issues more visible and easily updatable if a new target shares an
18
+ issue with an old one or if a platform issue is fixed.
19
+
20
+ The files exported here are mostly organized as one file per function. The rest
21
+ of the RxPlayer logic can then import those files when platform-specific
22
+ work-arounds and implementations are needed.
18
23
 
19
24
  It is important that those files do not import any code from the RxPlayer,
20
- outside of utils (in `src/utils`).
25
+ outside of utils (in `src/utils`) to prevent both circular dependencies and
26
+ having a difficult-to-follow (a.k.a. "spaghetti") code architecture.
21
27
 
22
28
  Any EME-related (Encrypted Media Extensions, specific APIs linked to DRM) are
23
29
  implemented in the `eme` subdirectory.
@@ -27,7 +27,6 @@ import { getLeftSizeOfRange } from "../../utils/ranges";
27
27
  import SharedReference, {
28
28
  IReadOnlySharedReference,
29
29
  } from "../../utils/reference";
30
- import takeFirstSet from "../../utils/take_first_set";
31
30
  import TaskCanceller, {
32
31
  CancellationSignal,
33
32
  } from "../../utils/task_canceller";
@@ -114,24 +113,15 @@ export default function createAdaptiveRepresentationSelector(
114
113
  ) : IRepresentationEstimatorResponse {
115
114
  const { type } = context.adaptation;
116
115
  const bandwidthEstimator = _getBandwidthEstimator(type);
117
- const manualBitrate = takeFirstSet<IReadOnlySharedReference<number>>(
118
- manualBitrates[type],
119
- manualBitrateDefaultRef);
120
- const minAutoBitrate = takeFirstSet<IReadOnlySharedReference<number>>(
121
- minAutoBitrates[type],
122
- minAutoBitrateDefaultRef);
123
- const maxAutoBitrate = takeFirstSet<IReadOnlySharedReference<number>>(
124
- maxAutoBitrates[type],
125
- maxAutoBitrateDefaultRef);
126
- const initialBitrate = takeFirstSet<number>(initialBitrates[type], 0);
116
+ const manualBitrate = manualBitrates[type] ?? manualBitrateDefaultRef;
117
+ const minAutoBitrate = minAutoBitrates[type] ?? minAutoBitrateDefaultRef;
118
+ const maxAutoBitrate = maxAutoBitrates[type] ?? maxAutoBitrateDefaultRef;
119
+ const initialBitrate = initialBitrates[type] ?? 0;
127
120
  const filters = {
128
- limitWidth: takeFirstSet<IReadOnlySharedReference<number | undefined>>(
129
- throttlers.limitWidth[type],
130
- limitWidthDefaultRef),
131
- throttleBitrate: takeFirstSet<IReadOnlySharedReference<number>>(
132
- throttlers.throttleBitrate[type],
133
- throttlers.throttle[type],
134
- throttleBitrateDefaultRef),
121
+ limitWidth: throttlers.limitWidth[type] ?? limitWidthDefaultRef,
122
+ throttleBitrate: throttlers.throttleBitrate[type] ??
123
+ throttlers.throttle[type] ??
124
+ throttleBitrateDefaultRef,
135
125
  };
136
126
  return getEstimateReference({ bandwidthEstimator,
137
127
  context,
@@ -16,7 +16,6 @@
16
16
 
17
17
  import { Representation } from "../../../manifest";
18
18
  import arrayFind from "../../../utils/array_find";
19
- import takeFirstSet from "../../../utils/take_first_set";
20
19
 
21
20
  /**
22
21
  * Filter representations based on their width:
@@ -32,8 +31,7 @@ export default function filterByWidth(
32
31
  ) : Representation[] {
33
32
  const sortedRepsByWidth = representations
34
33
  .slice() // clone
35
- .sort((a, b) => takeFirstSet<number>(a.width, 0) -
36
- takeFirstSet<number>(b.width, 0));
34
+ .sort((a, b) => (a.width ?? 0) - (b.width ?? 0));
37
35
 
38
36
  const repWithMaxWidth = arrayFind(sortedRepsByWidth, (representation) =>
39
37
  typeof representation.width === "number" &&
@@ -379,7 +379,7 @@ class Player extends EventEmitter<IPublicAPIEvent> {
379
379
  // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1194624
380
380
  videoElement.preload = "auto";
381
381
 
382
- this.version = /* PLAYER_VERSION */"3.32.2-dev.2023102600";
382
+ this.version = /* PLAYER_VERSION */"3.32.2-dev.2023110700";
383
383
  this.log = log;
384
384
  this.state = "STOPPED";
385
385
  this.videoElement = videoElement;
@@ -3103,7 +3103,7 @@ class Player extends EventEmitter<IPublicAPIEvent> {
3103
3103
  return mediaElementTrackChoiceManager;
3104
3104
  }
3105
3105
  }
3106
- Player.version = /* PLAYER_VERSION */"3.32.2-dev.2023102600";
3106
+ Player.version = /* PLAYER_VERSION */"3.32.2-dev.2023110700";
3107
3107
 
3108
3108
  /** Every events sent by the RxPlayer's public API. */
3109
3109
  interface IPublicAPIEvent {
@@ -43,7 +43,6 @@ import normalizeLanguage from "../../../utils/languages";
43
43
  import objectAssign from "../../../utils/object_assign";
44
44
  import SharedReference from "../../../utils/reference";
45
45
  import SortedList from "../../../utils/sorted_list";
46
- import takeFirstSet from "../../../utils/take_first_set";
47
46
 
48
47
  /** Audio information stored for a single Period. */
49
48
  interface ITMPeriodAudioInfos {
@@ -1092,8 +1091,7 @@ function createTextPreferenceMatcher(
1092
1091
  * @returns {boolean}
1093
1092
  */
1094
1093
  return function matchTextPreference(textAdaptation : Adaptation) : boolean {
1095
- return takeFirstSet<string>(textAdaptation.normalizedLanguage,
1096
- "") === preferredTextTrack.normalized &&
1094
+ return (textAdaptation.normalizedLanguage ?? "") === preferredTextTrack.normalized &&
1097
1095
  (preferredTextTrack.closedCaption ? textAdaptation.isClosedCaption === true :
1098
1096
  textAdaptation.isClosedCaption !== true) &&
1099
1097
  (preferredTextTrack.forced === true ? textAdaptation.isForcedSubtitles === true :
@@ -23,7 +23,6 @@ import {
23
23
  Period,
24
24
  Representation,
25
25
  } from "../../../manifest";
26
- import takeFirstSet from "../../../utils/take_first_set";
27
26
  import BufferedHistory, {
28
27
  IBufferedHistoryEntry,
29
28
  } from "./buffered_history";
@@ -219,7 +218,7 @@ export default class SegmentInventory {
219
218
  // skip until first segment with at least `MINIMUM_SEGMENT_SIZE` past the
220
219
  // start of that range.
221
220
  while (thisSegment !== undefined &&
222
- (takeFirstSet<number>(thisSegment.bufferedEnd, thisSegment.end)
221
+ ((thisSegment.bufferedEnd ?? thisSegment.end)
223
222
  - rangeStart) < MINIMUM_SEGMENT_SIZE)
224
223
  {
225
224
  thisSegment = inventory[++inventoryIndex];
@@ -239,8 +238,7 @@ export default class SegmentInventory {
239
238
  inventory[indexBefore + numberOfSegmentToDelete - 1];
240
239
 
241
240
  lastDeletedSegmentInfos = {
242
- end: takeFirstSet<number>(lastDeletedSegment.bufferedEnd,
243
- lastDeletedSegment.end),
241
+ end: lastDeletedSegment.bufferedEnd ?? lastDeletedSegment.end,
244
242
  precizeEnd: lastDeletedSegment.precizeEnd,
245
243
  };
246
244
  log.debug(`SI: ${numberOfSegmentToDelete} segments GCed.`, bufferType);
@@ -259,8 +257,7 @@ export default class SegmentInventory {
259
257
 
260
258
  // If the current segment is actually completely outside that range (it
261
259
  // is contained in one of the next one), skip that part.
262
- if (rangeEnd -
263
- takeFirstSet<number>(thisSegment.bufferedStart, thisSegment.start)
260
+ if (rangeEnd - (thisSegment.bufferedStart ?? thisSegment.start)
264
261
  >= MINIMUM_SEGMENT_SIZE
265
262
  ) {
266
263
  guessBufferedStartFromRangeStart(thisSegment,
@@ -278,10 +275,8 @@ export default class SegmentInventory {
278
275
  thisSegment = inventory[++inventoryIndex];
279
276
 
280
277
  // Make contiguous until first segment outside that range
281
- let thisSegmentStart = takeFirstSet<number>(thisSegment.bufferedStart,
282
- thisSegment.start);
283
- let thisSegmentEnd = takeFirstSet<number>(thisSegment.bufferedEnd,
284
- thisSegment.end);
278
+ let thisSegmentStart = thisSegment.bufferedStart ?? thisSegment.start;
279
+ let thisSegmentEnd = thisSegment.bufferedEnd ?? thisSegment.end;
285
280
  const nextRangeStart = i < rangesLength - 1 ? buffered.start(i + 1) :
286
281
  undefined;
287
282
  while (thisSegment !== undefined &&
@@ -303,10 +298,8 @@ export default class SegmentInventory {
303
298
  thisSegment.bufferedStart = prevSegment.bufferedEnd;
304
299
  thisSegment = inventory[++inventoryIndex];
305
300
  if (thisSegment !== undefined) {
306
- thisSegmentStart = takeFirstSet<number>(thisSegment.bufferedStart,
307
- thisSegment.start);
308
- thisSegmentEnd = takeFirstSet<number>(thisSegment.bufferedEnd,
309
- thisSegment.end);
301
+ thisSegmentStart = thisSegment.bufferedStart ?? thisSegment.start;
302
+ thisSegmentEnd = thisSegment.bufferedEnd ?? thisSegment.end;
310
303
  }
311
304
  }
312
305
  }
@@ -26,7 +26,6 @@ import isNonEmptyString from "../../../utils/is_non_empty_string";
26
26
  import objectAssign from "../../../utils/object_assign";
27
27
  import { getFilenameIndexInUrl } from "../../../utils/resolve_url";
28
28
  import { hexToBytes } from "../../../utils/string_parsing";
29
- import takeFirstSet from "../../../utils/take_first_set";
30
29
  import { createBox } from "../../containers/isobmff";
31
30
  import {
32
31
  IContentProtectionKID,
@@ -258,7 +257,7 @@ function createSmoothStreamingParser(
258
257
  customAttributes,
259
258
  mimeType: fourCC !== undefined ? MIME_TYPES[fourCC] :
260
259
  fourCC,
261
- codecPrivateData: takeFirstSet<string>(codecPrivateData, "") };
260
+ codecPrivateData: codecPrivateData ?? "" };
262
261
  }
263
262
 
264
263
  default:
@@ -17,7 +17,6 @@
17
17
  import features from "../../features";
18
18
  import { ICdnMetadata } from "../../parsers/manifest";
19
19
  import request from "../../utils/request";
20
- import takeFirstSet from "../../utils/take_first_set";
21
20
  import { CancellationSignal } from "../../utils/task_canceller";
22
21
  import {
23
22
  IImageTrackSegmentData,
@@ -92,7 +91,7 @@ export function imageParser(
92
91
  throw new Error("Image data should not be downloaded in chunks");
93
92
  }
94
93
 
95
- const chunkOffset = takeFirstSet<number>(segment.timestampOffset, 0);
94
+ const chunkOffset = segment.timestampOffset ?? 0;
96
95
 
97
96
  // TODO image Parsing should be more on the buffer side, no?
98
97
  if (data === null || features.imageParser === null) {
@@ -29,7 +29,6 @@ import {
29
29
  } from "../../parsers/containers/matroska";
30
30
  import { BaseRepresentationIndex } from "../../parsers/manifest/dash";
31
31
  import isNullOrUndefined from "../../utils/is_null_or_undefined";
32
- import takeFirstSet from "../../utils/take_first_set";
33
32
  import {
34
33
  ISegmentContext,
35
34
  ISegmentParser,
@@ -106,7 +105,7 @@ export default function generateAudioVideoSegmentParser(
106
105
  segment,
107
106
  initTimescale) :
108
107
  null; // TODO extract time info from webm
109
- const chunkOffset = takeFirstSet<number>(segment.timestampOffset, 0);
108
+ const chunkOffset = segment.timestampOffset ?? 0;
110
109
 
111
110
  if (seemsToBeMP4) {
112
111
  const parsedEMSGs = parseEmsgBoxes(chunkData);
@@ -23,7 +23,6 @@ import {
23
23
  strToUtf8,
24
24
  utf8ToStr,
25
25
  } from "../../utils/string_parsing";
26
- import takeFirstSet from "../../utils/take_first_set";
27
26
  import {
28
27
  ISegmentContext,
29
28
  ISegmentParser,
@@ -114,7 +113,7 @@ function parseISOBMFFEmbeddedTextTrack(
114
113
  chunkBytes,
115
114
  chunkInfos,
116
115
  isChunked);
117
- const chunkOffset = takeFirstSet<number>(segment.timestampOffset, 0);
116
+ const chunkOffset = segment.timestampOffset ?? 0;
118
117
  return { segmentType: "media",
119
118
  chunkData,
120
119
  chunkSize: chunkBytes.length,
@@ -20,7 +20,6 @@ import {
20
20
  } from "../../parsers/containers/isobmff";
21
21
  import { getKeyIdFromInitSegment } from "../../parsers/containers/isobmff/utils";
22
22
  import { getTimeCodeScale } from "../../parsers/containers/matroska";
23
- import takeFirstSet from "../../utils/take_first_set";
24
23
  import {
25
24
  ISegmentContext,
26
25
  ISegmentParserParsedInitChunk,
@@ -91,7 +90,7 @@ export default function segmentParser(
91
90
  segment,
92
91
  initTimescale) :
93
92
  null; // TODO extract time info from webm
94
- const chunkOffset = takeFirstSet<number>(segment.timestampOffset, 0);
93
+ const chunkOffset = segment.timestampOffset ?? 0;
95
94
  return { segmentType: "media",
96
95
  chunkData,
97
96
  chunkSize: chunkData.length,
@@ -19,7 +19,6 @@ import {
19
19
  strToUtf8,
20
20
  utf8ToStr,
21
21
  } from "../../utils/string_parsing";
22
- import takeFirstSet from "../../utils/take_first_set";
23
22
  import {
24
23
  ILoadedTextSegmentFormat,
25
24
  ISegmentContext,
@@ -78,7 +77,7 @@ function parseISOBMFFEmbeddedTextTrack(
78
77
  chunkBytes,
79
78
  chunkInfos,
80
79
  isChunked);
81
- const chunkOffset = takeFirstSet<number>(segment.timestampOffset, 0);
80
+ const chunkOffset = segment.timestampOffset ?? 0;
82
81
  return { segmentType: "media",
83
82
  chunkData,
84
83
  chunkSize: chunkBytes.length,
@@ -125,7 +124,7 @@ function parsePlainTextTrack(
125
124
  textTrackData = data;
126
125
  }
127
126
  const chunkData = getPlainTextTrackData(content, textTrackData, isChunked);
128
- const chunkOffset = takeFirstSet<number>(segment.timestampOffset, 0);
127
+ const chunkOffset = segment.timestampOffset ?? 0;
129
128
  return { segmentType: "media",
130
129
  chunkData,
131
130
  chunkSize,
@@ -1,25 +0,0 @@
1
- /**
2
- * Copyright 2015 CANAL+ Group
3
- *
4
- * Licensed under the Apache License, Version 2.0 (the "License");
5
- * you may not use this file except in compliance with the License.
6
- * You may obtain a copy of the License at
7
- *
8
- * http://www.apache.org/licenses/LICENSE-2.0
9
- *
10
- * Unless required by applicable law or agreed to in writing, software
11
- * distributed under the License is distributed on an "AS IS" BASIS,
12
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- * See the License for the specific language governing permissions and
14
- * limitations under the License.
15
- */
16
- /**
17
- * Returns the first argument given different from undefined or null.
18
- * @param {...*} args
19
- * @returns {*}
20
- */
21
- export default function takeFirstSet<T>(a: T, b?: undefined | null | T): T;
22
- export default function takeFirstSet<T>(a: T | undefined | null, b: T): T;
23
- export default function takeFirstSet(a?: undefined | null, b?: undefined | null): undefined;
24
- export default function takeFirstSet<T>(a: undefined | null | T, b: undefined | null | T, c: T): T;
25
- export default function takeFirstSet<T>(...args: Array<T | null | undefined>): T | undefined;
@@ -1,32 +0,0 @@
1
- /**
2
- * Copyright 2015 CANAL+ Group
3
- *
4
- * Licensed under the Apache License, Version 2.0 (the "License");
5
- * you may not use this file except in compliance with the License.
6
- * You may obtain a copy of the License at
7
- *
8
- * http://www.apache.org/licenses/LICENSE-2.0
9
- *
10
- * Unless required by applicable law or agreed to in writing, software
11
- * distributed under the License is distributed on an "AS IS" BASIS,
12
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- * See the License for the specific language governing permissions and
14
- * limitations under the License.
15
- */
16
- import isNullOrUndefined from "./is_null_or_undefined";
17
- export default function takeFirstSet() {
18
- var args = [];
19
- for (var _i = 0; _i < arguments.length; _i++) {
20
- args[_i] = arguments[_i];
21
- }
22
- var i = 0;
23
- var len = args.length;
24
- while (i < len) {
25
- var arg = args[i];
26
- if (!isNullOrUndefined(arg)) {
27
- return arg;
28
- }
29
- i++;
30
- }
31
- return undefined;
32
- }
@@ -1,38 +0,0 @@
1
- /**
2
- * Copyright 2015 CANAL+ Group
3
- *
4
- * Licensed under the Apache License, Version 2.0 (the "License");
5
- * you may not use this file except in compliance with the License.
6
- * You may obtain a copy of the License at
7
- *
8
- * http://www.apache.org/licenses/LICENSE-2.0
9
- *
10
- * Unless required by applicable law or agreed to in writing, software
11
- * distributed under the License is distributed on an "AS IS" BASIS,
12
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- * See the License for the specific language governing permissions and
14
- * limitations under the License.
15
- */
16
-
17
- import takeFirstSet from "../take_first_set";
18
-
19
- describe("utils - takeFirstSet", () => {
20
- it("should return undefined with no argument", () => {
21
- expect(takeFirstSet()).toEqual(undefined);
22
- });
23
-
24
- it("should return undefined with only undefined or null arguments", () => {
25
- expect(takeFirstSet(undefined, undefined, undefined)).toEqual(undefined);
26
- expect(takeFirstSet(null, null, null, null)).toEqual(undefined);
27
- expect(takeFirstSet(undefined, null, null, undefined)).toEqual(undefined);
28
- expect(takeFirstSet(null, null, null, undefined)).toEqual(undefined);
29
- });
30
-
31
- it("should return the first set argument", () => {
32
- const obj1 = { a: 4 };
33
- const obj2 = { b: 12 };
34
-
35
- expect(takeFirstSet<unknown>(undefined, null, obj1, obj2))
36
- .toEqual(obj1);
37
- });
38
- });
@@ -1,53 +0,0 @@
1
- /**
2
- * Copyright 2015 CANAL+ Group
3
- *
4
- * Licensed under the Apache License, Version 2.0 (the "License");
5
- * you may not use this file except in compliance with the License.
6
- * You may obtain a copy of the License at
7
- *
8
- * http://www.apache.org/licenses/LICENSE-2.0
9
- *
10
- * Unless required by applicable law or agreed to in writing, software
11
- * distributed under the License is distributed on an "AS IS" BASIS,
12
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- * See the License for the specific language governing permissions and
14
- * limitations under the License.
15
- */
16
-
17
- import isNullOrUndefined from "./is_null_or_undefined";
18
-
19
- /**
20
- * Returns the first argument given different from undefined or null.
21
- * @param {...*} args
22
- * @returns {*}
23
- */
24
- export default function takeFirstSet<T>(
25
- a : T,
26
- b? : undefined | null | T
27
- ) : T;
28
- export default function takeFirstSet<T>(a : T | undefined | null, b : T) : T;
29
- export default function takeFirstSet(
30
- a? : undefined|null,
31
- b? : undefined|null
32
- ) : undefined;
33
- export default function takeFirstSet<T>(
34
- a : undefined|null|T,
35
- b : undefined|null|T,
36
- c : T
37
- ) : T;
38
- export default function takeFirstSet<T>(...args : Array<T|null|undefined>) : T |
39
- undefined;
40
- export default function takeFirstSet<T>(
41
- ...args : Array<T|null|undefined>
42
- ) : T | undefined {
43
- let i = 0;
44
- const len = args.length;
45
- while (i < len) {
46
- const arg = args[i];
47
- if (!isNullOrUndefined(arg)) {
48
- return arg;
49
- }
50
- i++;
51
- }
52
- return undefined;
53
- }