@oddin-gg/havik-player 2.7.0 → 2.9.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
@@ -11,6 +11,23 @@ export declare interface AudioTrackInfo {
11
11
  default: boolean;
12
12
  }
13
13
 
14
+ /**
15
+ * The API base URL for a named environment.
16
+ *
17
+ * Mode A takes {@link HavikEnv} directly (`createPlayer({ env: 'production' })`).
18
+ * Mode B and Mode C still take a `baseUrl`, so call this to get one rather
19
+ * than copying a hostname into your own config:
20
+ *
21
+ * ```ts
22
+ * resolveStream({ baseUrl: baseUrlForEnv('production'), matchUrn, credential });
23
+ * ```
24
+ *
25
+ * Throws on an unrecognized value rather than returning undefined — callers
26
+ * reach this from plain JS where the type gives no protection, and a silent
27
+ * undefined becomes a relative URL against the embedding page.
28
+ */
29
+ export declare function baseUrlForEnv(env: HavikEnv): string;
30
+
14
31
  /**
15
32
  * Boots the iframe-side player and speaks the postMessage protocol with the host.
16
33
  * The api-key is NEVER accepted over postMessage. The bridge fails CLOSED: with no
@@ -53,18 +70,53 @@ export declare interface CatalogTournament {
53
70
  export declare function clearDeviceId(): void;
54
71
 
55
72
  /**
56
- * Mode A — managed player. Owns the <video> and a bundled hls.js, wiring
57
- * LL-HLS + DRM automatically. With `waitForLive`, arms on an upcoming match and
58
- * auto-plays the instant it goes live. Resolves to a Player as soon as it is
59
- * armed/attached — terminal errors (404/410/401/...) reject; the live wait does
60
- * not block and is surfaced via 'waiting' events.
73
+ * Endpoint selection, enforced at COMPILE time.
74
+ *
75
+ * `env` and `baseUrl` are both optional on {@link CreatePlayerOptions} so it
76
+ * stays an interface others can `extend` and `Partial<>`. That alone would
77
+ * make "neither given" type-check and fail only in the browser, which is a
78
+ * guarantee this SDK used to have while `baseUrl` was required. These two
79
+ * overloads put it back at the call site without changing the interface: one
80
+ * names `env` and forbids `baseUrl`, the other the reverse, so neither and
81
+ * both are both "no overload matches this call".
82
+ *
83
+ * resolveEndpoint still enforces the same rule at runtime — the overloads do
84
+ * nothing for a JavaScript caller, and that is most of the embed surface.
61
85
  */
62
- export declare function createPlayer(opts: CreatePlayerOptions): Promise<Player>;
86
+ export declare function createPlayer(opts: CreatePlayerOptions & {
87
+ env: HavikEnv;
88
+ baseUrl?: never;
89
+ }): Promise<Player>;
90
+
91
+ export declare function createPlayer(opts: CreatePlayerOptions & {
92
+ baseUrl: string;
93
+ env?: never;
94
+ }): Promise<Player>;
63
95
 
64
96
  export declare interface CreatePlayerOptions {
65
97
  /** The <video> element the SDK will own. */
66
98
  video: HTMLVideoElement;
67
- baseUrl: string;
99
+ /**
100
+ * Which Oddin environment to play against. Prefer this over
101
+ * {@link baseUrl}: the host is then correct by construction, and so is
102
+ * everything derived from it (the SSE events host, the QoE beacons host).
103
+ *
104
+ * Exactly one of `env` or {@link baseUrl} is required. Passing both is an
105
+ * error rather than a precedence rule — the two disagreeing is precisely
106
+ * the misconfiguration worth refusing, and silently preferring one would
107
+ * point a player at an environment nobody chose.
108
+ */
109
+ env?: HavikEnv;
110
+ /**
111
+ * API base URL, when {@link env} does not name it. Use this for a
112
+ * deployment the named environments do not cover: your own CDN or gateway
113
+ * fronting the streams API, the CN plane, or a pinned build that must
114
+ * outlive a domain change.
115
+ *
116
+ * Note that a base which is not a `feed[-dev].<domain>` host derives no QoE
117
+ * beacons endpoint, so pair it with `analytics: { endpoint }`.
118
+ */
119
+ baseUrl?: string;
68
120
  matchUrn: string;
69
121
  credential: CredentialSource;
70
122
  /**
@@ -321,6 +373,23 @@ export declare interface EmbedConfig {
321
373
  autoplay?: boolean;
322
374
  muted?: boolean;
323
375
  waitForLive?: WaitForLive;
376
+ /**
377
+ * QoE beacons, forwarded verbatim to {@link createPlayer}. Same meaning as
378
+ * there: `false` opts out, `{ endpoint }` names a beacons host.
379
+ *
380
+ * Mode C needs this for the same reason Mode A does, and until now had no
381
+ * way to say it. An embed whose `baseUrl` is not a `feed[-dev].<domain>`
382
+ * host — a CDN or gateway fronting the streams API — derives no beacons
383
+ * endpoint, so analytics is off and stays off. Without this option the
384
+ * only remedy was to move `baseUrl` back onto a feed host, which is not a
385
+ * choice an integrator who fronts the API deliberately can make.
386
+ *
387
+ * INJECTED CONFIG ONLY: unlike every other field here, this is not read
388
+ * from the query string. See {@link readConfig}.
389
+ */
390
+ analytics?: boolean | {
391
+ endpoint?: string;
392
+ };
324
393
  }
325
394
 
326
395
  export declare interface EmbedHandle {
@@ -477,6 +546,16 @@ export declare type FrameToHost = {
477
546
 
478
547
  export declare function getDeviceId(): string;
479
548
 
549
+ /**
550
+ * A named Oddin environment.
551
+ *
552
+ * - `integration` — the shared pre-production stack. Where customers build
553
+ * and test against real matches.
554
+ * - `production` — the production stack. A separate distribution, not an
555
+ * alias of integration.
556
+ */
557
+ export declare type HavikEnv = 'integration' | 'production';
558
+
480
559
  export declare interface HavikTheme {
481
560
  /** Primary accent (play button, progress fill, live dot, focus). */
482
561
  accent: string;
@@ -611,6 +690,18 @@ export declare interface MountEmbedOptions {
611
690
  container: HTMLElement;
612
691
  /** URL of the hosted embed page, e.g. `https://player-dev.oddin-video.gg/embed/`. */
613
692
  src: string;
693
+ /**
694
+ * API base URL, forwarded to the embed page as a query parameter.
695
+ *
696
+ * ⚠️ QoE beacons: the beacons endpoint is derived from this host by
697
+ * convention (`feed[-dev].<domain>` → `beacons[-dev].<domain>`). If your
698
+ * base is NOT a feed host, nothing derives and analytics is off — and
699
+ * `mountEmbed` CANNOT fix it, because the only way to name an endpoint is
700
+ * {@link EmbedConfig.analytics}, which the embed page reads from injected
701
+ * config and deliberately never from the query string (a link must not be
702
+ * able to redirect a session's telemetry). Host the embed page yourself
703
+ * and inject `window.HAVIK_EMBED_CONFIG` with `analytics: { endpoint }`.
704
+ */
614
705
  baseUrl: string;
615
706
  matchUrn: string;
616
707
  /**
package/dist/index.d.ts CHANGED
@@ -11,6 +11,23 @@ export declare interface AudioTrackInfo {
11
11
  default: boolean;
12
12
  }
13
13
 
14
+ /**
15
+ * The API base URL for a named environment.
16
+ *
17
+ * Mode A takes {@link HavikEnv} directly (`createPlayer({ env: 'production' })`).
18
+ * Mode B and Mode C still take a `baseUrl`, so call this to get one rather
19
+ * than copying a hostname into your own config:
20
+ *
21
+ * ```ts
22
+ * resolveStream({ baseUrl: baseUrlForEnv('production'), matchUrn, credential });
23
+ * ```
24
+ *
25
+ * Throws on an unrecognized value rather than returning undefined — callers
26
+ * reach this from plain JS where the type gives no protection, and a silent
27
+ * undefined becomes a relative URL against the embedding page.
28
+ */
29
+ export declare function baseUrlForEnv(env: HavikEnv): string;
30
+
14
31
  /**
15
32
  * Boots the iframe-side player and speaks the postMessage protocol with the host.
16
33
  * The api-key is NEVER accepted over postMessage. The bridge fails CLOSED: with no
@@ -53,18 +70,53 @@ export declare interface CatalogTournament {
53
70
  export declare function clearDeviceId(): void;
54
71
 
55
72
  /**
56
- * Mode A — managed player. Owns the <video> and a bundled hls.js, wiring
57
- * LL-HLS + DRM automatically. With `waitForLive`, arms on an upcoming match and
58
- * auto-plays the instant it goes live. Resolves to a Player as soon as it is
59
- * armed/attached — terminal errors (404/410/401/...) reject; the live wait does
60
- * not block and is surfaced via 'waiting' events.
73
+ * Endpoint selection, enforced at COMPILE time.
74
+ *
75
+ * `env` and `baseUrl` are both optional on {@link CreatePlayerOptions} so it
76
+ * stays an interface others can `extend` and `Partial<>`. That alone would
77
+ * make "neither given" type-check and fail only in the browser, which is a
78
+ * guarantee this SDK used to have while `baseUrl` was required. These two
79
+ * overloads put it back at the call site without changing the interface: one
80
+ * names `env` and forbids `baseUrl`, the other the reverse, so neither and
81
+ * both are both "no overload matches this call".
82
+ *
83
+ * resolveEndpoint still enforces the same rule at runtime — the overloads do
84
+ * nothing for a JavaScript caller, and that is most of the embed surface.
61
85
  */
62
- export declare function createPlayer(opts: CreatePlayerOptions): Promise<Player>;
86
+ export declare function createPlayer(opts: CreatePlayerOptions & {
87
+ env: HavikEnv;
88
+ baseUrl?: never;
89
+ }): Promise<Player>;
90
+
91
+ export declare function createPlayer(opts: CreatePlayerOptions & {
92
+ baseUrl: string;
93
+ env?: never;
94
+ }): Promise<Player>;
63
95
 
64
96
  export declare interface CreatePlayerOptions {
65
97
  /** The <video> element the SDK will own. */
66
98
  video: HTMLVideoElement;
67
- baseUrl: string;
99
+ /**
100
+ * Which Oddin environment to play against. Prefer this over
101
+ * {@link baseUrl}: the host is then correct by construction, and so is
102
+ * everything derived from it (the SSE events host, the QoE beacons host).
103
+ *
104
+ * Exactly one of `env` or {@link baseUrl} is required. Passing both is an
105
+ * error rather than a precedence rule — the two disagreeing is precisely
106
+ * the misconfiguration worth refusing, and silently preferring one would
107
+ * point a player at an environment nobody chose.
108
+ */
109
+ env?: HavikEnv;
110
+ /**
111
+ * API base URL, when {@link env} does not name it. Use this for a
112
+ * deployment the named environments do not cover: your own CDN or gateway
113
+ * fronting the streams API, the CN plane, or a pinned build that must
114
+ * outlive a domain change.
115
+ *
116
+ * Note that a base which is not a `feed[-dev].<domain>` host derives no QoE
117
+ * beacons endpoint, so pair it with `analytics: { endpoint }`.
118
+ */
119
+ baseUrl?: string;
68
120
  matchUrn: string;
69
121
  credential: CredentialSource;
70
122
  /**
@@ -321,6 +373,23 @@ export declare interface EmbedConfig {
321
373
  autoplay?: boolean;
322
374
  muted?: boolean;
323
375
  waitForLive?: WaitForLive;
376
+ /**
377
+ * QoE beacons, forwarded verbatim to {@link createPlayer}. Same meaning as
378
+ * there: `false` opts out, `{ endpoint }` names a beacons host.
379
+ *
380
+ * Mode C needs this for the same reason Mode A does, and until now had no
381
+ * way to say it. An embed whose `baseUrl` is not a `feed[-dev].<domain>`
382
+ * host — a CDN or gateway fronting the streams API — derives no beacons
383
+ * endpoint, so analytics is off and stays off. Without this option the
384
+ * only remedy was to move `baseUrl` back onto a feed host, which is not a
385
+ * choice an integrator who fronts the API deliberately can make.
386
+ *
387
+ * INJECTED CONFIG ONLY: unlike every other field here, this is not read
388
+ * from the query string. See {@link readConfig}.
389
+ */
390
+ analytics?: boolean | {
391
+ endpoint?: string;
392
+ };
324
393
  }
325
394
 
326
395
  export declare interface EmbedHandle {
@@ -477,6 +546,16 @@ export declare type FrameToHost = {
477
546
 
478
547
  export declare function getDeviceId(): string;
479
548
 
549
+ /**
550
+ * A named Oddin environment.
551
+ *
552
+ * - `integration` — the shared pre-production stack. Where customers build
553
+ * and test against real matches.
554
+ * - `production` — the production stack. A separate distribution, not an
555
+ * alias of integration.
556
+ */
557
+ export declare type HavikEnv = 'integration' | 'production';
558
+
480
559
  export declare interface HavikTheme {
481
560
  /** Primary accent (play button, progress fill, live dot, focus). */
482
561
  accent: string;
@@ -611,6 +690,18 @@ export declare interface MountEmbedOptions {
611
690
  container: HTMLElement;
612
691
  /** URL of the hosted embed page, e.g. `https://player-dev.oddin-video.gg/embed/`. */
613
692
  src: string;
693
+ /**
694
+ * API base URL, forwarded to the embed page as a query parameter.
695
+ *
696
+ * ⚠️ QoE beacons: the beacons endpoint is derived from this host by
697
+ * convention (`feed[-dev].<domain>` → `beacons[-dev].<domain>`). If your
698
+ * base is NOT a feed host, nothing derives and analytics is off — and
699
+ * `mountEmbed` CANNOT fix it, because the only way to name an endpoint is
700
+ * {@link EmbedConfig.analytics}, which the embed page reads from injected
701
+ * config and deliberately never from the query string (a link must not be
702
+ * able to redirect a session's telemetry). Host the embed page yourself
703
+ * and inject `window.HAVIK_EMBED_CONFIG` with `analytics: { endpoint }`.
704
+ */
614
705
  baseUrl: string;
615
706
  matchUrn: string;
616
707
  /**