@oddin-gg/havik-player 2.18.0 → 2.20.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/index.d.cts CHANGED
@@ -622,8 +622,30 @@ export declare type FrameToHost = {
622
622
  type: 'oddin:error';
623
623
  code: PlaybackErrorCode;
624
624
  message: string;
625
+ /** Set with code GEO_DENIED: the viewer's country the server refused (alpha-2). */
626
+ country?: string;
625
627
  };
626
628
 
629
+ /**
630
+ * Whether a fullscreen presentation for `video` can work, by the same
631
+ * ladder enterVideoFullscreen walks. False means a request is KNOWN to
632
+ * fail, so the caller should hide its button:
633
+ *
634
+ * - the element API exists on `container` (or the video) but the document
635
+ * reports `fullscreenEnabled === false` — the Fullscreen spec sets that
636
+ * exactly when permissions policy blocks the feature, which is what a
637
+ * cross-origin iframe without `fullscreen` in its `allow` list looks
638
+ * like (prefixed `webkitFullscreenEnabled` on older Safari);
639
+ * - no element API at all, media already loaded, and the video does not
640
+ * offer the video-native presentation either (a webview with nothing).
641
+ *
642
+ * True otherwise — including "not known yet": with no element API and
643
+ * media not loaded (iPhone before the first play) the video-native flag
644
+ * is not readable, so the answer stays optimistic. Re-check on
645
+ * `loadedmetadata`; the managed control bar does.
646
+ */
647
+ export declare function fullscreenSupported(video: HTMLVideoElement, container?: HTMLElement): boolean;
648
+
627
649
  export declare function getDeviceId(): string;
628
650
 
629
651
  /**
@@ -852,10 +874,15 @@ export declare class PlaybackError extends Error {
852
874
  * far-future matches.
853
875
  */
854
876
  readonly liveStartsAtMs?: number;
877
+ /**
878
+ * Set for GEO_DENIED: the viewer's country the server refused, as an
879
+ * upper-case ISO 3166-1 alpha-2 tag (e.g. "RU"). Absent on every other code.
880
+ */
881
+ readonly country?: string;
855
882
  constructor(code: PlaybackErrorCode, httpStatus: number, message: string, init?: PlaybackErrorInit);
856
883
  }
857
884
 
858
- export declare type PlaybackErrorCode = 'INVALID_URN' | 'NOT_FOUND' | 'GONE' | 'TOO_EARLY' | 'UNAVAILABLE' | 'UNAUTHORIZED' | 'FORBIDDEN' | 'DRM_CLIENT' | 'RATE_LIMITED' | 'INTERNAL' | 'NETWORK' | 'TIMEOUT' | 'ABORTED';
885
+ export declare type PlaybackErrorCode = 'INVALID_URN' | 'NOT_FOUND' | 'GEO_DENIED' | 'GONE' | 'TOO_EARLY' | 'UNAVAILABLE' | 'UNAUTHORIZED' | 'FORBIDDEN' | 'DRM_CLIENT' | 'RATE_LIMITED' | 'INTERNAL' | 'NETWORK' | 'TIMEOUT' | 'ABORTED';
859
886
 
860
887
  export declare interface PlaybackErrorInit {
861
888
  retryAfterMs?: number;
@@ -868,6 +895,11 @@ export declare interface PlaybackErrorInit {
868
895
  * matches without a separate catalog call.
869
896
  */
870
897
  liveStartsAtMs?: number;
898
+ /**
899
+ * The viewer's country as the server saw it (upper-case ISO 3166-1 alpha-2),
900
+ * carried on a GEO_DENIED body so the player can name it.
901
+ */
902
+ country?: string;
871
903
  cause?: unknown;
872
904
  }
873
905
 
@@ -997,6 +1029,14 @@ export declare interface Player {
997
1029
  enterFullscreen(): Promise<boolean>;
998
1030
  /** Leave fullscreen (element or video-native). Safe when not fullscreen. */
999
1031
  exitFullscreen(): Promise<void>;
1032
+ /**
1033
+ * Whether enterFullscreen can work here: false when the page's permissions
1034
+ * policy blocks fullscreen (an iframe without `fullscreen` in `allow`) or
1035
+ * the platform has no mechanism, so a custom UI can hide its button. Stays
1036
+ * true before media loads on iPhone (not knowable yet); re-check on the
1037
+ * video's `loadedmetadata`.
1038
+ */
1039
+ fullscreenSupported(): boolean;
1000
1040
  /** Retry playback after an error (re-resolves and re-attaches). */
1001
1041
  retry(): Promise<void>;
1002
1042
  /** Re-resolve playback (refreshes the signed license URL) and re-attach. */
@@ -1300,7 +1340,7 @@ export declare interface WatchStatusOptions {
1300
1340
  onChange: (status: MatchStatus) => void;
1301
1341
  /**
1302
1342
  * Fired on a poll error. Polling continues, except after a terminal answer
1303
- * about the URN itself (`NOT_FOUND`, `GONE`, `INVALID_URN`): the watcher
1343
+ * about the URN itself (`NOT_FOUND`, `GONE`, `GEO_DENIED`, `INVALID_URN`): the watcher
1304
1344
  * stops on its own and this is the last call it makes.
1305
1345
  */
1306
1346
  onError?: (err: PlaybackError) => void;
package/dist/index.d.ts CHANGED
@@ -622,8 +622,30 @@ export declare type FrameToHost = {
622
622
  type: 'oddin:error';
623
623
  code: PlaybackErrorCode;
624
624
  message: string;
625
+ /** Set with code GEO_DENIED: the viewer's country the server refused (alpha-2). */
626
+ country?: string;
625
627
  };
626
628
 
629
+ /**
630
+ * Whether a fullscreen presentation for `video` can work, by the same
631
+ * ladder enterVideoFullscreen walks. False means a request is KNOWN to
632
+ * fail, so the caller should hide its button:
633
+ *
634
+ * - the element API exists on `container` (or the video) but the document
635
+ * reports `fullscreenEnabled === false` — the Fullscreen spec sets that
636
+ * exactly when permissions policy blocks the feature, which is what a
637
+ * cross-origin iframe without `fullscreen` in its `allow` list looks
638
+ * like (prefixed `webkitFullscreenEnabled` on older Safari);
639
+ * - no element API at all, media already loaded, and the video does not
640
+ * offer the video-native presentation either (a webview with nothing).
641
+ *
642
+ * True otherwise — including "not known yet": with no element API and
643
+ * media not loaded (iPhone before the first play) the video-native flag
644
+ * is not readable, so the answer stays optimistic. Re-check on
645
+ * `loadedmetadata`; the managed control bar does.
646
+ */
647
+ export declare function fullscreenSupported(video: HTMLVideoElement, container?: HTMLElement): boolean;
648
+
627
649
  export declare function getDeviceId(): string;
628
650
 
629
651
  /**
@@ -852,10 +874,15 @@ export declare class PlaybackError extends Error {
852
874
  * far-future matches.
853
875
  */
854
876
  readonly liveStartsAtMs?: number;
877
+ /**
878
+ * Set for GEO_DENIED: the viewer's country the server refused, as an
879
+ * upper-case ISO 3166-1 alpha-2 tag (e.g. "RU"). Absent on every other code.
880
+ */
881
+ readonly country?: string;
855
882
  constructor(code: PlaybackErrorCode, httpStatus: number, message: string, init?: PlaybackErrorInit);
856
883
  }
857
884
 
858
- export declare type PlaybackErrorCode = 'INVALID_URN' | 'NOT_FOUND' | 'GONE' | 'TOO_EARLY' | 'UNAVAILABLE' | 'UNAUTHORIZED' | 'FORBIDDEN' | 'DRM_CLIENT' | 'RATE_LIMITED' | 'INTERNAL' | 'NETWORK' | 'TIMEOUT' | 'ABORTED';
885
+ export declare type PlaybackErrorCode = 'INVALID_URN' | 'NOT_FOUND' | 'GEO_DENIED' | 'GONE' | 'TOO_EARLY' | 'UNAVAILABLE' | 'UNAUTHORIZED' | 'FORBIDDEN' | 'DRM_CLIENT' | 'RATE_LIMITED' | 'INTERNAL' | 'NETWORK' | 'TIMEOUT' | 'ABORTED';
859
886
 
860
887
  export declare interface PlaybackErrorInit {
861
888
  retryAfterMs?: number;
@@ -868,6 +895,11 @@ export declare interface PlaybackErrorInit {
868
895
  * matches without a separate catalog call.
869
896
  */
870
897
  liveStartsAtMs?: number;
898
+ /**
899
+ * The viewer's country as the server saw it (upper-case ISO 3166-1 alpha-2),
900
+ * carried on a GEO_DENIED body so the player can name it.
901
+ */
902
+ country?: string;
871
903
  cause?: unknown;
872
904
  }
873
905
 
@@ -997,6 +1029,14 @@ export declare interface Player {
997
1029
  enterFullscreen(): Promise<boolean>;
998
1030
  /** Leave fullscreen (element or video-native). Safe when not fullscreen. */
999
1031
  exitFullscreen(): Promise<void>;
1032
+ /**
1033
+ * Whether enterFullscreen can work here: false when the page's permissions
1034
+ * policy blocks fullscreen (an iframe without `fullscreen` in `allow`) or
1035
+ * the platform has no mechanism, so a custom UI can hide its button. Stays
1036
+ * true before media loads on iPhone (not knowable yet); re-check on the
1037
+ * video's `loadedmetadata`.
1038
+ */
1039
+ fullscreenSupported(): boolean;
1000
1040
  /** Retry playback after an error (re-resolves and re-attaches). */
1001
1041
  retry(): Promise<void>;
1002
1042
  /** Re-resolve playback (refreshes the signed license URL) and re-attach. */
@@ -1300,7 +1340,7 @@ export declare interface WatchStatusOptions {
1300
1340
  onChange: (status: MatchStatus) => void;
1301
1341
  /**
1302
1342
  * Fired on a poll error. Polling continues, except after a terminal answer
1303
- * about the URN itself (`NOT_FOUND`, `GONE`, `INVALID_URN`): the watcher
1343
+ * about the URN itself (`NOT_FOUND`, `GONE`, `GEO_DENIED`, `INVALID_URN`): the watcher
1304
1344
  * stops on its own and this is the last call it makes.
1305
1345
  */
1306
1346
  onError?: (err: PlaybackError) => void;