@kkcompany/ott-player 0.5.11 → 0.5.12

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/CHANGELOG.md CHANGED
@@ -2,7 +2,17 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
- ### [0.5.11](https://gitlab.kkinternal.com/kks-web/blahaj/compare/v0.3.93...v0.5.11) (2026-08-13)
5
+ ### [0.5.12](https://gitlab.kkinternal.com/kks-web/blahaj/compare/player@0.5.11...player@0.5.12) (2026-09-03)
6
+
7
+ ### Bug Fixes
8
+
9
+ * [SUN-7797] gate sessions on tab lock ([938698a](https://gitlab.kkinternal.com/kks-web/blahaj/commit/938698a40b60d334b554eead162f0d09e84cacba))
10
+
11
+ ### [0.5.11](https://gitlab.kkinternal.com/kks-web/blahaj/compare/player@0.5.10...player@0.5.11) (2026-08-13)
12
+
13
+ ### Bug Fixes
14
+
15
+ * bump @kkcompany/player to v2.27.2 ([1a75dd0](https://gitlab.kkinternal.com/kks-web/blahaj/commit/1a75dd0))
6
16
 
7
17
  ### [0.5.10](https://gitlab.kkinternal.com/kks-web/blahaj/compare/player@0.5.9...player@0.5.10) (2026-08-07)
8
18
 
package/dist/index.cjs CHANGED
@@ -453,18 +453,19 @@ const lockRenewTime = 3e3;
453
453
  const ensureTabLock = () => {
454
454
  let saved = {};
455
455
  try {
456
- saved = JSON.parse(localStorage[storageKey]);
456
+ const value = localStorage.getItem(storageKey);
457
+ saved = value ? JSON.parse(value) : {};
457
458
  } catch (e) {
458
- console.log("Can read saved data for tab lock.", e);
459
+ console.log("Cannot read saved data for tab lock.", e);
459
460
  }
460
461
  const { expireTime } = saved;
461
- if (Date.now() <= expireTime) return;
462
+ if (expireTime >= Date.now()) return { acquired: false };
462
463
  const id = uuidv4$1();
463
464
  const renewLock = () => {
464
- localStorage[storageKey] = JSON.stringify({
465
+ localStorage.setItem(storageKey, JSON.stringify({
465
466
  id,
466
467
  expireTime: Date.now() + lockRenewTime * 3
467
- });
468
+ }));
468
469
  };
469
470
  renewLock();
470
471
  const renewInterval = setInterval(renewLock, lockRenewTime);
@@ -472,11 +473,18 @@ const ensureTabLock = () => {
472
473
  clearInterval(renewInterval);
473
474
  window.removeEventListener("beforeunload", releaseLock);
474
475
  window.removeEventListener("unload", releaseLock);
475
- localStorage.removeItem(storageKey);
476
+ try {
477
+ if (JSON.parse(localStorage.getItem(storageKey) || "{}").id === id) localStorage.removeItem(storageKey);
478
+ } catch (e) {
479
+ console.log("Cannot read saved data for tab lock.", e);
480
+ }
476
481
  };
477
482
  window.addEventListener("beforeunload", releaseLock);
478
483
  window.addEventListener("unload", releaseLock);
479
- return releaseLock;
484
+ return {
485
+ acquired: true,
486
+ release: releaseLock
487
+ };
480
488
  };
481
489
 
482
490
  //#endregion
@@ -971,7 +979,7 @@ var preload_default = preload;
971
979
 
972
980
  //#endregion
973
981
  //#region package.json
974
- var version = "0.5.11";
982
+ var version = "0.5.12";
975
983
 
976
984
  //#endregion
977
985
  //#region src/constants.js
@@ -1016,6 +1024,20 @@ const getEnterpriseDrmHeaders = ({ token, tokenType = "playback" }) => {
1016
1024
  };
1017
1025
  const sessionCache = {};
1018
1026
  const getCastState = () => window.cast?.framework?.CastContext.getInstance()?.getCastState() || CastState.NO_DEVICES_AVAILABLE;
1027
+ const useTabLock = () => {
1028
+ const lockRef = (0, react.useRef)();
1029
+ (0, react.useEffect)(() => () => {
1030
+ lockRef.current?.release();
1031
+ lockRef.current = void 0;
1032
+ }, []);
1033
+ return (0, react.useCallback)(() => {
1034
+ if (lockRef.current) return true;
1035
+ const lock = ensureTabLock();
1036
+ if (!lock.acquired) return false;
1037
+ lockRef.current = lock;
1038
+ return true;
1039
+ }, []);
1040
+ };
1019
1041
  const PremiumPlusPlayer = ({ controls, preload: preload$1 = "auto", preloadList = [], currentTime, quality, sourceType, host, accessToken, deviceId, headers, params, contentType, contentId, contentKey = `${contentType}/${contentId}`, autoplayNext, thumbnailSeeking, plugins = [], settings: appSettings = {}, coverImageUrl, coverImageDisplay = "auto", recommendation, uiElements: { castButton, ...uiElements } = {}, playerRef, children, slotProps, sessionRequest, preconnect, onError, onApiError, onBack, onPlaybackStateChange, onPlayerLoaded, onChange, onPlaybackApiResponse, sendLog, playbackState: appPlaybackState, turnOnSkipOpening, shouldHideSkipButton = false, playerToModuleErrorCodeMap, drmOptions = {}, ...rest }) => {
1020
1042
  const components = {
1021
1043
  LinearEnd: __kkcompany_player_react.LiveEnd,
@@ -1025,20 +1047,13 @@ const PremiumPlusPlayer = ({ controls, preload: preload$1 = "auto", preloadList
1025
1047
  const corePlayerRef = (0, react.useRef)();
1026
1048
  const lastSession$1 = (0, react.useRef)({});
1027
1049
  const logTarget = (0, react.useRef)();
1050
+ const acquireTabLock = useTabLock();
1028
1051
  const preferAppTime = (0, react.useRef)(currentTime >= 0);
1029
1052
  const [playbackState, setPlaybackState] = (0, react.useState)(() => getCastState() === CastState.CONNECTED ? "casting" : "initial");
1030
1053
  const [playbackInfo, setPlaybackInfo] = (0, react.useState)({ sources: [] });
1031
1054
  const [contentData, setContentData] = (0, react.useState)({});
1032
1055
  const [targetPlaybackState, setTargetPlaybackState] = (0, react.useState)(appPlaybackState);
1033
1056
  const [uiState, dispatch] = (0, react.useReducer)(reduceUi, getInitUiState({ recommendation: true }));
1034
- (0, react.useEffect)(() => {
1035
- const revokeLock = ensureTabLock();
1036
- if (!revokeLock) videoRef.current.dispatchEvent(Object.assign(new CustomEvent("error"), { error: {
1037
- name: "PlaycraftApiError",
1038
- code: 10021
1039
- } }));
1040
- return revokeLock;
1041
- }, []);
1042
1057
  const api = (0, react.useMemo)(() => (0, __kkcompany_player_modules.createApi)({
1043
1058
  host,
1044
1059
  accessToken,
@@ -1069,15 +1084,18 @@ const PremiumPlusPlayer = ({ controls, preload: preload$1 = "auto", preloadList
1069
1084
  }
1070
1085
  };
1071
1086
  const getPlaybackStatus = (0, react.useCallback)(() => ({
1072
- ...(0, __kkcompany_player_core.getMediaTime)(videoRef.current, {
1073
- player: corePlayerRef.current,
1074
- plugins: allPlugins
1075
- }),
1087
+ ...(0, __kkcompany_player_core.getMediaTime)(videoRef.current, { player: corePlayerRef.current }),
1076
1088
  ...contentType?.startsWith("live") && { currentTime: Math.floor(Date.now() / 1e3) }
1077
1089
  }), []);
1078
1090
  let handleReset;
1079
- let allPlugins;
1080
1091
  const load = async () => {
1092
+ if (!acquireTabLock()) {
1093
+ videoRef.current?.dispatchEvent(Object.assign(new CustomEvent("error"), { error: {
1094
+ name: "PlaycraftApiError",
1095
+ code: 10021
1096
+ } }));
1097
+ return;
1098
+ }
1081
1099
  if (await lastSession$1.current.request === "cancel") return;
1082
1100
  const restPlayerName = ["shaka", "bitmovin"].find((name) => name in rest);
1083
1101
  if (logTarget.current?.reset) {
package/dist/index.mjs CHANGED
@@ -429,18 +429,19 @@ const lockRenewTime = 3e3;
429
429
  const ensureTabLock = () => {
430
430
  let saved = {};
431
431
  try {
432
- saved = JSON.parse(localStorage[storageKey]);
432
+ const value = localStorage.getItem(storageKey);
433
+ saved = value ? JSON.parse(value) : {};
433
434
  } catch (e) {
434
- console.log("Can read saved data for tab lock.", e);
435
+ console.log("Cannot read saved data for tab lock.", e);
435
436
  }
436
437
  const { expireTime } = saved;
437
- if (Date.now() <= expireTime) return;
438
+ if (expireTime >= Date.now()) return { acquired: false };
438
439
  const id = uuidv4$1();
439
440
  const renewLock = () => {
440
- localStorage[storageKey] = JSON.stringify({
441
+ localStorage.setItem(storageKey, JSON.stringify({
441
442
  id,
442
443
  expireTime: Date.now() + lockRenewTime * 3
443
- });
444
+ }));
444
445
  };
445
446
  renewLock();
446
447
  const renewInterval = setInterval(renewLock, lockRenewTime);
@@ -448,11 +449,18 @@ const ensureTabLock = () => {
448
449
  clearInterval(renewInterval);
449
450
  window.removeEventListener("beforeunload", releaseLock);
450
451
  window.removeEventListener("unload", releaseLock);
451
- localStorage.removeItem(storageKey);
452
+ try {
453
+ if (JSON.parse(localStorage.getItem(storageKey) || "{}").id === id) localStorage.removeItem(storageKey);
454
+ } catch (e) {
455
+ console.log("Cannot read saved data for tab lock.", e);
456
+ }
452
457
  };
453
458
  window.addEventListener("beforeunload", releaseLock);
454
459
  window.addEventListener("unload", releaseLock);
455
- return releaseLock;
460
+ return {
461
+ acquired: true,
462
+ release: releaseLock
463
+ };
456
464
  };
457
465
 
458
466
  //#endregion
@@ -947,7 +955,7 @@ var preload_default = preload;
947
955
 
948
956
  //#endregion
949
957
  //#region package.json
950
- var version = "0.5.11";
958
+ var version = "0.5.12";
951
959
 
952
960
  //#endregion
953
961
  //#region src/constants.js
@@ -992,6 +1000,20 @@ const getEnterpriseDrmHeaders = ({ token, tokenType = "playback" }) => {
992
1000
  };
993
1001
  const sessionCache = {};
994
1002
  const getCastState = () => window.cast?.framework?.CastContext.getInstance()?.getCastState() || CastState.NO_DEVICES_AVAILABLE;
1003
+ const useTabLock = () => {
1004
+ const lockRef = useRef();
1005
+ useEffect(() => () => {
1006
+ lockRef.current?.release();
1007
+ lockRef.current = void 0;
1008
+ }, []);
1009
+ return useCallback(() => {
1010
+ if (lockRef.current) return true;
1011
+ const lock = ensureTabLock();
1012
+ if (!lock.acquired) return false;
1013
+ lockRef.current = lock;
1014
+ return true;
1015
+ }, []);
1016
+ };
995
1017
  const PremiumPlusPlayer = ({ controls, preload: preload$1 = "auto", preloadList = [], currentTime, quality, sourceType, host, accessToken, deviceId, headers, params, contentType, contentId, contentKey = `${contentType}/${contentId}`, autoplayNext, thumbnailSeeking, plugins = [], settings: appSettings = {}, coverImageUrl, coverImageDisplay = "auto", recommendation, uiElements: { castButton, ...uiElements } = {}, playerRef, children, slotProps, sessionRequest, preconnect, onError, onApiError, onBack, onPlaybackStateChange, onPlayerLoaded, onChange, onPlaybackApiResponse, sendLog, playbackState: appPlaybackState, turnOnSkipOpening, shouldHideSkipButton = false, playerToModuleErrorCodeMap, drmOptions = {}, ...rest }) => {
996
1018
  const components = {
997
1019
  LinearEnd: LiveEnd$1,
@@ -1001,20 +1023,13 @@ const PremiumPlusPlayer = ({ controls, preload: preload$1 = "auto", preloadList
1001
1023
  const corePlayerRef = useRef();
1002
1024
  const lastSession$1 = useRef({});
1003
1025
  const logTarget = useRef();
1026
+ const acquireTabLock = useTabLock();
1004
1027
  const preferAppTime = useRef(currentTime >= 0);
1005
1028
  const [playbackState, setPlaybackState] = useState(() => getCastState() === CastState.CONNECTED ? "casting" : "initial");
1006
1029
  const [playbackInfo, setPlaybackInfo] = useState({ sources: [] });
1007
1030
  const [contentData, setContentData] = useState({});
1008
1031
  const [targetPlaybackState, setTargetPlaybackState] = useState(appPlaybackState);
1009
1032
  const [uiState, dispatch] = useReducer(reduceUi, getInitUiState({ recommendation: true }));
1010
- useEffect(() => {
1011
- const revokeLock = ensureTabLock();
1012
- if (!revokeLock) videoRef.current.dispatchEvent(Object.assign(new CustomEvent("error"), { error: {
1013
- name: "PlaycraftApiError",
1014
- code: 10021
1015
- } }));
1016
- return revokeLock;
1017
- }, []);
1018
1033
  const api = useMemo(() => createApi({
1019
1034
  host,
1020
1035
  accessToken,
@@ -1045,15 +1060,18 @@ const PremiumPlusPlayer = ({ controls, preload: preload$1 = "auto", preloadList
1045
1060
  }
1046
1061
  };
1047
1062
  const getPlaybackStatus = useCallback(() => ({
1048
- ...getMediaTime(videoRef.current, {
1049
- player: corePlayerRef.current,
1050
- plugins: allPlugins
1051
- }),
1063
+ ...getMediaTime(videoRef.current, { player: corePlayerRef.current }),
1052
1064
  ...contentType?.startsWith("live") && { currentTime: Math.floor(Date.now() / 1e3) }
1053
1065
  }), []);
1054
1066
  let handleReset;
1055
- let allPlugins;
1056
1067
  const load = async () => {
1068
+ if (!acquireTabLock()) {
1069
+ videoRef.current?.dispatchEvent(Object.assign(new CustomEvent("error"), { error: {
1070
+ name: "PlaycraftApiError",
1071
+ code: 10021
1072
+ } }));
1073
+ return;
1074
+ }
1057
1075
  if (await lastSession$1.current.request === "cancel") return;
1058
1076
  const restPlayerName = ["shaka", "bitmovin"].find((name) => name in rest);
1059
1077
  if (logTarget.current?.reset) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kkcompany/ott-player",
3
- "version": "0.5.11",
3
+ "version": "0.5.12",
4
4
  "exports": {
5
5
  ".": {
6
6
  "import": "./dist/index.mjs",