eb-player 2.5.3 → 2.7.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/build/eb-player.css +1 -1
- package/dist/build/ebplayer.bundle.js +102 -102
- package/dist/build/types/src/core/browser-support.d.ts +29 -0
- package/dist/build/types/src/core/config.d.ts +32 -0
- package/dist/build/types/src/core/errors.d.ts +39 -0
- package/dist/build/types/src/core/event-bus.d.ts +4 -0
- package/dist/build/types/src/core/i18n.d.ts +8 -0
- package/dist/build/types/src/core/types.d.ts +2 -0
- package/dist/build/types/src/eb-player.d.ts +7 -0
- package/dist/build/types/src/engines/base-engine.d.ts +13 -0
- package/dist/build/types/src/engines/cdn-token-manager.d.ts +31 -0
- package/dist/build/types/src/skin/base-component.d.ts +10 -0
- package/dist/build/types/src/skin/controls/volume-control.d.ts +13 -3
- package/dist/build/types/src/skin/index.d.ts +1 -0
- package/dist/build/types/src/skin/overlays/error-message.d.ts +2 -1
- package/dist/build/types/src/skin/overlays/subtitle-overlay.d.ts +30 -0
- package/dist/build/types/src/utils/play-quietly.d.ts +17 -0
- package/dist/build/types/src/utils/telemetry.d.ts +28 -0
- package/dist/eb-player.css +1 -1
- package/package.json +5 -3
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime feature floor of the player.
|
|
3
|
+
*
|
|
4
|
+
* The bundle's *syntax* floor is ES2017 (see scripts/check-syntax-floor.ts),
|
|
5
|
+
* which parses on Chrome 55+, Safari 10.1+ and Firefox 52+. Some of those
|
|
6
|
+
* engines still lack runtime APIs the player cannot work without:
|
|
7
|
+
*
|
|
8
|
+
* - Proxy — the reactive PlayerState store (Chrome 49, Safari 10)
|
|
9
|
+
* - AbortController — every subscription/listener cleanup (Chrome 66,
|
|
10
|
+
* Safari 12.1, Firefox 57)
|
|
11
|
+
*
|
|
12
|
+
* On such a browser `start()` used to throw a bare ReferenceError from deep
|
|
13
|
+
* inside PlayerController's constructor, leaving the integrator's container
|
|
14
|
+
* as an empty white box. This module lets start() detect the gap up front
|
|
15
|
+
* and show a readable message instead, using only pre-ES2015 DOM APIs.
|
|
16
|
+
*/
|
|
17
|
+
export declare const REQUIRED_RUNTIME_FEATURES: readonly ["Proxy", "AbortController"];
|
|
18
|
+
/**
|
|
19
|
+
* Returns the names of the required runtime features that are not
|
|
20
|
+
* constructors on `scope` (defaults to `window`).
|
|
21
|
+
*/
|
|
22
|
+
export declare function findMissingRuntimeFeatures(scope?: Record<string, unknown>): string[];
|
|
23
|
+
/**
|
|
24
|
+
* Replaces the container's content with the skin's error overlay markup
|
|
25
|
+
* (same class names as ErrorMessage, so the shipped CSS styles it) carrying
|
|
26
|
+
* the translated "browser not supported" text. Plain DOM calls only: this
|
|
27
|
+
* runs precisely on the browsers where lit-html/PlayerState cannot.
|
|
28
|
+
*/
|
|
29
|
+
export declare function renderUnsupportedBrowser(container: HTMLElement, lang?: string): void;
|
|
@@ -7,6 +7,18 @@
|
|
|
7
7
|
* 3. Fixes the JSON.parse/stringify bug in generator/mergeConfig.js by
|
|
8
8
|
* passing function values by reference instead of serializing them
|
|
9
9
|
*/
|
|
10
|
+
import type { PlayerErrorInfo } from './errors';
|
|
11
|
+
/** Player-rendered subtitles. Setting `subtitleStyle` (even `{}`) switches subtitle rendering from the browser to the player. Numbers are pixels. */
|
|
12
|
+
export interface SubtitleStyle {
|
|
13
|
+
fontFamily?: string;
|
|
14
|
+
fontSize?: string | number;
|
|
15
|
+
color?: string;
|
|
16
|
+
backgroundColor?: string;
|
|
17
|
+
/** Distance of the text from the bottom of the video while the controls are hidden. */
|
|
18
|
+
bottom?: string | number;
|
|
19
|
+
/** Same, while the controls are visible (lifts the text above the seekbar). */
|
|
20
|
+
bottomWithControls?: string | number;
|
|
21
|
+
}
|
|
10
22
|
export interface SkinColors {
|
|
11
23
|
general: string;
|
|
12
24
|
progressBar: string;
|
|
@@ -138,6 +150,26 @@ export interface PlayerConfig {
|
|
|
138
150
|
token: string | undefined;
|
|
139
151
|
tokenType: string | undefined;
|
|
140
152
|
srcInTokenRequest: boolean;
|
|
153
|
+
/**
|
|
154
|
+
* Called for every user-visible player error, with a stable `code` (see
|
|
155
|
+
* `PlayerErrorCode`), the English diagnostic `message` and the
|
|
156
|
+
* `localizedMessage` the overlay shows. Fires for errors raised during
|
|
157
|
+
* start() too, which `player.on('error')` cannot see (no reference yet).
|
|
158
|
+
*/
|
|
159
|
+
onError?: ((error: PlayerErrorInfo) => void) | null;
|
|
160
|
+
/**
|
|
161
|
+
* Override or add UI text: `{ fr: { 'error.geoblocked': '...' } }`. Error
|
|
162
|
+
* overlay keys are `error.<code lower-cased>`, e.g. `error.drm_error`.
|
|
163
|
+
* Locales are en / fr / ar / es; text in `{name}` form is interpolated only
|
|
164
|
+
* where the player passes variables.
|
|
165
|
+
*/
|
|
166
|
+
messages?: Record<string, Record<string, string>> | null;
|
|
167
|
+
/**
|
|
168
|
+
* Render subtitles in the player instead of the browser, to control font,
|
|
169
|
+
* size and position. `null` (default) keeps native rendering.
|
|
170
|
+
*/
|
|
171
|
+
subtitleStyle?: SubtitleStyle | null;
|
|
172
|
+
sentryDsn: string | undefined;
|
|
141
173
|
defaultAudio: string | string[] | undefined;
|
|
142
174
|
defaultSubtitle: string | string[] | undefined;
|
|
143
175
|
forceAutoplay: boolean;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { PlayerState } from './types';
|
|
2
|
+
import type { TypedEventBus } from './event-bus';
|
|
3
|
+
import type { I18n } from './i18n';
|
|
4
|
+
/**
|
|
5
|
+
* Stable, documented error codes. Integrators key their own translations and
|
|
6
|
+
* telemetry on these; the English `message` next to them is diagnostic prose
|
|
7
|
+
* and may change between releases. The i18n key for a code is
|
|
8
|
+
* `error.<code lower-cased>` (see `errorMessageKey`).
|
|
9
|
+
*/
|
|
10
|
+
export declare const PlayerErrorCode: {
|
|
11
|
+
readonly STREAM_UNAVAILABLE: "STREAM_UNAVAILABLE";
|
|
12
|
+
readonly GEOBLOCKED: "GEOBLOCKED";
|
|
13
|
+
readonly HLS_INIT_FAILED: "HLS_INIT_FAILED";
|
|
14
|
+
readonly DASH_INIT_FAILED: "DASH_INIT_FAILED";
|
|
15
|
+
readonly DRM_ERROR: "DRM_ERROR";
|
|
16
|
+
readonly LOAD_NEVER_STARTED: "LOAD_NEVER_STARTED";
|
|
17
|
+
readonly NO_VIDEO_ELEMENT: "NO_VIDEO_ELEMENT";
|
|
18
|
+
};
|
|
19
|
+
export type PlayerErrorCodeValue = (typeof PlayerErrorCode)[keyof typeof PlayerErrorCode];
|
|
20
|
+
/** Payload of the public `error` event / `config.onError` callback. */
|
|
21
|
+
export interface PlayerErrorInfo {
|
|
22
|
+
/** Stable code — one of `PlayerErrorCode`. */
|
|
23
|
+
code: string;
|
|
24
|
+
/** Diagnostic message (English, unlocalized). */
|
|
25
|
+
message: string;
|
|
26
|
+
/** The text the error overlay shows, in the configured `lang`. */
|
|
27
|
+
localizedMessage: string;
|
|
28
|
+
}
|
|
29
|
+
/** i18n key holding the user-facing text for an error code. */
|
|
30
|
+
export declare function errorMessageKey(code: string): string;
|
|
31
|
+
/**
|
|
32
|
+
* The one place a fatal, user-visible error is surfaced: sets the code before
|
|
33
|
+
* the message (the overlay re-renders on `error`), and announces it on the bus.
|
|
34
|
+
* Distinct from `error-fatal`, which has side effects (P2P teardown, intro
|
|
35
|
+
* fall-through) and is only emitted for a subset of failures.
|
|
36
|
+
*/
|
|
37
|
+
export declare function reportError(state: PlayerState, bus: TypedEventBus | null | undefined, code: PlayerErrorCodeValue, message: string): void;
|
|
38
|
+
/** Overlay text for an error: the code's translation when one exists, else the raw message. */
|
|
39
|
+
export declare function localizeError(code: string | null, rawMessage: string, i18n: I18n | null): string;
|
|
@@ -25,6 +25,14 @@ export declare class I18n {
|
|
|
25
25
|
* Useful for skin components adding their own translation keys in Phase 3.
|
|
26
26
|
*/
|
|
27
27
|
addTranslations(entries: TranslationMap): void;
|
|
28
|
+
/**
|
|
29
|
+
* Register integrator overrides shaped `{ locale: { key: text } }` (the
|
|
30
|
+
* `config.messages` shape). Locale codes are reduced to their language part
|
|
31
|
+
* ('fr-CA' -> 'fr'); keys are the same ones t() looks up (e.g. 'error.geoblocked').
|
|
32
|
+
*/
|
|
33
|
+
addMessages(messages: Record<string, Record<string, string>>): void;
|
|
34
|
+
/** Whether any locale defines this key (a missing key would echo back as itself from t()). */
|
|
35
|
+
has(key: string): boolean;
|
|
28
36
|
/**
|
|
29
37
|
* Look up a translation key in the current locale.
|
|
30
38
|
* Falls back to English if not found in current locale.
|
|
@@ -45,6 +45,8 @@ export interface StateMap {
|
|
|
45
45
|
currentSubtitleTrack: number;
|
|
46
46
|
playbackRate: number;
|
|
47
47
|
error: string | null;
|
|
48
|
+
/** Stable code of the current error (see `PlayerErrorCode`); null when `error` is null or was set without a code. */
|
|
49
|
+
errorCode: string | null;
|
|
48
50
|
src: string;
|
|
49
51
|
isFullscreen: boolean;
|
|
50
52
|
isPip: boolean;
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
import { AVAILABLE_THEMES, THEME_LAYOUTS } from './core/index';
|
|
18
18
|
import type { PlayerState } from './core/types';
|
|
19
19
|
import type { PlayerConfig } from './core/config';
|
|
20
|
+
import type { PlayerErrorInfo } from './core/errors';
|
|
20
21
|
/**
|
|
21
22
|
* The PlayerReference returned by start().
|
|
22
23
|
* Gives consumers direct control over the active stream.
|
|
@@ -30,6 +31,12 @@ export interface PlayerReference {
|
|
|
30
31
|
destroy(): void;
|
|
31
32
|
/** Current player state (read-only reference to the reactive state store). */
|
|
32
33
|
readonly state: PlayerState;
|
|
34
|
+
/**
|
|
35
|
+
* Subscribe to user-visible player errors, each with a stable `code`
|
|
36
|
+
* (see `PlayerErrorCode`). Returns an unsubscribe function. Errors raised
|
|
37
|
+
* while start() is still running are only reachable via `config.onError`.
|
|
38
|
+
*/
|
|
39
|
+
on(event: 'error', listener: (error: PlayerErrorInfo) => void): () => void;
|
|
33
40
|
}
|
|
34
41
|
/**
|
|
35
42
|
* Start the player with the given config.
|
|
@@ -26,6 +26,14 @@ export declare abstract class BaseEngine extends EngineStateSync {
|
|
|
26
26
|
*/
|
|
27
27
|
protected loadSourceUrl: string;
|
|
28
28
|
private watchdog;
|
|
29
|
+
/**
|
|
30
|
+
* Every native video listener bound by bindVideoEvents(), so detach() can
|
|
31
|
+
* remove them itself. They are also registered with `{ signal }`, but
|
|
32
|
+
* Chromium < 90, Safari < 15 and Firefox < 86 silently ignore that option:
|
|
33
|
+
* on those engines the listeners outlived destroy() and kept writing a
|
|
34
|
+
* disposed PlayerState on every timeupdate (Sentry FORJA-FRONTWEB-5B9/5BA).
|
|
35
|
+
*/
|
|
36
|
+
private videoListeners;
|
|
29
37
|
/**
|
|
30
38
|
* Promise that resolves when the engine driver (hls.js/dash.js) is created
|
|
31
39
|
* and ready for integration (e.g., P2P SDK). Resolved inside onAttach().
|
|
@@ -49,6 +57,11 @@ export declare abstract class BaseEngine extends EngineStateSync {
|
|
|
49
57
|
*/
|
|
50
58
|
setLoadSource(src: string): void;
|
|
51
59
|
protected bindVideoEvents(video: HTMLVideoElement, state: PlayerState, signal: AbortSignal): void;
|
|
60
|
+
/**
|
|
61
|
+
* Removes every listener bound by bindVideoEvents() — the explicit half of
|
|
62
|
+
* the cleanup that `{ signal }` was supposed to do on its own.
|
|
63
|
+
*/
|
|
64
|
+
private unbindVideoEvents;
|
|
52
65
|
protected abstract recoverFromStall(attempt: number): void;
|
|
53
66
|
protected abstract onAttach(): Promise<void> | void;
|
|
54
67
|
protected abstract onDetach(): void;
|
|
@@ -136,6 +136,17 @@ export declare class CDNTokenManager {
|
|
|
136
136
|
sourceUrl: string | null;
|
|
137
137
|
private resetAttemptCounterTimeout;
|
|
138
138
|
private inFlightFetch;
|
|
139
|
+
/**
|
|
140
|
+
* Consecutive CDN-side rejections (see notifyCdnRejection) handled without
|
|
141
|
+
* an intervening resetCdnRejectionCount(). Capped at maxRetries so a token
|
|
142
|
+
* that keeps getting rejected for a non-expiration reason (geo-blocking,
|
|
143
|
+
* revoked entitlement, IP mismatch...) doesn't make us mint a fresh token
|
|
144
|
+
* forever — after the cap, notifyCdnRejection stops forcing refreshes and
|
|
145
|
+
* the normal engine error handling (fatal/non-fatal escalation) takes over.
|
|
146
|
+
*/
|
|
147
|
+
private cdnRejectionCount;
|
|
148
|
+
/** Set by notifyCdnRejection; consumed once by the next updateUrlWithTokenParams call. */
|
|
149
|
+
private forceRefreshOnce;
|
|
139
150
|
constructor({ token, tokenType, srcInTokenRequest, extraParamsCallback, onCDNTokenError, maxRetries, retryInterval, expirationMarginInSeconds }: CDNTokenManagerOptions);
|
|
140
151
|
private resetAttemptCounter;
|
|
141
152
|
private _fetchDefaultToken;
|
|
@@ -149,6 +160,26 @@ export declare class CDNTokenManager {
|
|
|
149
160
|
url: string;
|
|
150
161
|
}): Promise<string>;
|
|
151
162
|
isTokenExpired(expirationTime: number | string | null | undefined): boolean;
|
|
163
|
+
/**
|
|
164
|
+
* Signals that the CDN itself (not the token generator) rejected a request
|
|
165
|
+
* signed with the current token — e.g. a 403 on a playlist fetch.
|
|
166
|
+
* isTokenExpired()'s margin only compares against the token's own
|
|
167
|
+
* `expires`, so a token the CDN already refused can still look "fresh" and
|
|
168
|
+
* get replayed unchanged on the next retry/reload. This forces the next
|
|
169
|
+
* updateUrlWithTokenParams() call to mint a new token regardless of that
|
|
170
|
+
* margin.
|
|
171
|
+
*
|
|
172
|
+
* Capped at maxRetries consecutive calls (cleared by
|
|
173
|
+
* resetCdnRejectionCount on a subsequent successful load): a freshly-minted
|
|
174
|
+
* token that also gets rejected is not an expiration problem — e.g.
|
|
175
|
+
* geo-blocking or a revoked entitlement — and retrying forever would only
|
|
176
|
+
* hammer the token generator and the CDN for no benefit. Past the cap this
|
|
177
|
+
* returns false and does nothing, leaving the engine's own error handling
|
|
178
|
+
* (fatal/non-fatal escalation) to take over.
|
|
179
|
+
*/
|
|
180
|
+
notifyCdnRejection(): boolean;
|
|
181
|
+
/** Call after a request signed with the current token succeeds at the CDN. */
|
|
182
|
+
resetCdnRejectionCount(): void;
|
|
152
183
|
destroy(): void;
|
|
153
184
|
static appendTokenParams(urlString: string, token: string | null, expires: number | string | null, tokenPath: string | null): string;
|
|
154
185
|
static appendAkamaiTokenParams(urlString: string, hdnea: string): string;
|
|
@@ -63,6 +63,16 @@ export declare abstract class BaseComponent {
|
|
|
63
63
|
/**
|
|
64
64
|
* Renders the component into this.el using lit-html.
|
|
65
65
|
* No-op if el is null (e.g., after disconnect()).
|
|
66
|
+
*
|
|
67
|
+
* A render that throws is contained: lit-html keeps its parts alive through
|
|
68
|
+
* comment markers inside the component's subtree, and a DOM rewriter
|
|
69
|
+
* outside the player (page translation, an extension) that rebuilds that
|
|
70
|
+
* markup without the markers breaks the part for good — every later render
|
|
71
|
+
* throws the same `this._$AA.nextSibling is null` and, with a component
|
|
72
|
+
* re-rendering on each state tick, that is thousands of identical errors
|
|
73
|
+
* per session (Sentry FORJA-FRONTWEB-5EZ..5F1). The failure is logged once,
|
|
74
|
+
* the view is unsubscribed from state/bus updates, and render() becomes a
|
|
75
|
+
* no-op. disconnect() stays safe to call afterwards.
|
|
66
76
|
*/
|
|
67
77
|
protected render(): void;
|
|
68
78
|
}
|
|
@@ -4,17 +4,27 @@ import { BaseComponent } from '../base-component';
|
|
|
4
4
|
* Volume control with mute toggle button and draggable slider.
|
|
5
5
|
*
|
|
6
6
|
* - Mute button emits 'mute-toggle'
|
|
7
|
-
* - Slider uses Pointer Events API (pointerdown/pointermove/pointerup)
|
|
7
|
+
* - Slider uses Pointer Events API (pointerdown/pointermove/pointerup/pointercancel)
|
|
8
8
|
* - Slider fill width reflects current volume (0% to 100%)
|
|
9
9
|
* - When muted, fill shows 0% visually
|
|
10
|
+
*
|
|
11
|
+
* The document-level drag listeners are stable instance methods, never
|
|
12
|
+
* per-drag closures: a second pointerdown landing during a drag (a second
|
|
13
|
+
* finger on a phone) used to overwrite the stored closure, so the first
|
|
14
|
+
* drag's listeners could never be removed again and kept calling
|
|
15
|
+
* eventToVolume() against a track rect that pointerup had already nulled
|
|
16
|
+
* (Sentry FORJA-FRONTWEB-5E3/5E4). With one function reference per event
|
|
17
|
+
* type, addEventListener is idempotent and removeEventListener always pairs.
|
|
10
18
|
*/
|
|
11
19
|
export declare class VolumeControl extends BaseComponent {
|
|
12
20
|
private trackRect;
|
|
13
|
-
private
|
|
14
|
-
private
|
|
21
|
+
private readonly onDocumentPointerMove;
|
|
22
|
+
private readonly onDocumentPointerUp;
|
|
23
|
+
private readonly onDocumentPointerCancel;
|
|
15
24
|
protected onConnect(): void;
|
|
16
25
|
private eventToVolume;
|
|
17
26
|
private handlePointerDown;
|
|
27
|
+
private endDrag;
|
|
18
28
|
private getVolumeIcon;
|
|
19
29
|
protected template(): TemplateResult;
|
|
20
30
|
}
|
|
@@ -15,6 +15,7 @@ export { SettingsPanel } from './controls/settings-panel';
|
|
|
15
15
|
export { Seekbar } from './controls/seekbar';
|
|
16
16
|
export { LoadingSpinner } from './overlays/loading-spinner';
|
|
17
17
|
export { ErrorMessage } from './overlays/error-message';
|
|
18
|
+
export { SubtitleOverlay } from './overlays/subtitle-overlay';
|
|
18
19
|
export { SocialsOverlay } from './overlays/socials-overlay';
|
|
19
20
|
export { InfoOverlay } from './overlays/info-overlay';
|
|
20
21
|
export { AutoHideController } from './controllers/auto-hide';
|
|
@@ -4,7 +4,8 @@ import { BaseComponent } from '../base-component';
|
|
|
4
4
|
* Error message overlay.
|
|
5
5
|
*
|
|
6
6
|
* Visible when state.error is not null.
|
|
7
|
-
* Shows the
|
|
7
|
+
* Shows the translation registered for state.errorCode (`error.<code>`, overridable
|
|
8
|
+
* through config.messages), falling back to the raw state.error string.
|
|
8
9
|
* Has a retry button that emits 'request-reload'.
|
|
9
10
|
*/
|
|
10
11
|
export declare class ErrorMessage extends BaseComponent {
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { TemplateResult } from 'lit-html';
|
|
2
|
+
import { BaseComponent } from '../base-component';
|
|
3
|
+
/**
|
|
4
|
+
* Renders subtitle cues in the player's own DOM so integrators control font,
|
|
5
|
+
* size and position (native `::cue` can style text but cannot move it).
|
|
6
|
+
*
|
|
7
|
+
* Only mounted when `config.subtitleStyle` is set; otherwise the browser
|
|
8
|
+
* renders cues natively, exactly as before. Works from the video's TextTracks,
|
|
9
|
+
* so it does not depend on which engine created them: a track an engine
|
|
10
|
+
* switches to `showing` is switched to `hidden` (still firing `cuechange`) and
|
|
11
|
+
* drawn here instead; a track set back to `disabled` stops being drawn.
|
|
12
|
+
*
|
|
13
|
+
* Not mounted-in behaviour: iOS uses the native player, which draws its own.
|
|
14
|
+
* WebVTT cue settings (`line`, `position`, `align`) are ignored — position is
|
|
15
|
+
* `subtitleStyle.bottom` / `bottomWithControls`.
|
|
16
|
+
*/
|
|
17
|
+
export declare class SubtitleOverlay extends BaseComponent {
|
|
18
|
+
private video;
|
|
19
|
+
private readonly taken;
|
|
20
|
+
private listRoot;
|
|
21
|
+
private readonly onTracksChange;
|
|
22
|
+
private readonly onCueChange;
|
|
23
|
+
protected onConnect(): void;
|
|
24
|
+
disconnect(): void;
|
|
25
|
+
protected template(): TemplateResult;
|
|
26
|
+
private applyStyle;
|
|
27
|
+
private syncTracks;
|
|
28
|
+
private paint;
|
|
29
|
+
private renderCue;
|
|
30
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Call `video.play()` and swallow its rejection.
|
|
3
|
+
*
|
|
4
|
+
* play() returns a promise that rejects with `AbortError` whenever pause() —
|
|
5
|
+
* or a new load — interrupts the pending play request. That is the normal
|
|
6
|
+
* outcome of a fast pause after play, an ad break, a cast hand-over or a
|
|
7
|
+
* source switch, never something the caller can act on, and left unhandled
|
|
8
|
+
* it reaches the page as an unhandled promise rejection (Sentry issues 18
|
|
9
|
+
* and W, ~420 users/day on forja.ma). Browsers predating the promise return
|
|
10
|
+
* (and jsdom) return undefined, so the catch is only attached when there is
|
|
11
|
+
* something to attach it to.
|
|
12
|
+
*/
|
|
13
|
+
/** Anything with a media-element-shaped play(): HTMLVideoElement, or the poster loop's minimal media handle. */
|
|
14
|
+
export interface Playable {
|
|
15
|
+
play(): unknown;
|
|
16
|
+
}
|
|
17
|
+
export declare function playQuietly(video: Playable): void;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kicks off loading the Sentry Browser SDK from a CDN (see SENTRY_LOADER_URL)
|
|
3
|
+
* and initializing it with the given DSN. Fire-and-forget: does not return a
|
|
4
|
+
* promise the caller could await, and instrumentedFetch() below never waits
|
|
5
|
+
* on it either — network calls (notably the CDN token generator retry path)
|
|
6
|
+
* must never gain latency from telemetry loading.
|
|
7
|
+
*
|
|
8
|
+
* A page can host multiple player instances (see src/eb-player.ts's
|
|
9
|
+
* `instances` map); Sentry's client is inherently page-global, so this is a
|
|
10
|
+
* module-level singleton guarded against double-init. A second call with a
|
|
11
|
+
* different DSN is a no-op past a warning — reconciling two Sentry projects
|
|
12
|
+
* on one page is a host-app concern, not something this player can resolve.
|
|
13
|
+
*/
|
|
14
|
+
export declare function initTelemetry(dsn: string | undefined): void;
|
|
15
|
+
/**
|
|
16
|
+
* Drop-in replacement for `fetch(url, init)` that additionally records a
|
|
17
|
+
* response-time span and captures errors to Sentry, when telemetry is
|
|
18
|
+
* enabled and ready. Never changes the resolved value or the rejection a
|
|
19
|
+
* caller would have seen from a plain fetch() — callers keep every existing
|
|
20
|
+
* status check / retry / body-parsing line untouched.
|
|
21
|
+
*
|
|
22
|
+
* `name` is a fixed, non-secret label identifying the call site (e.g.
|
|
23
|
+
* 'cdn-token:bunny') — the request URL itself is never sent to Sentry.
|
|
24
|
+
*
|
|
25
|
+
* If Sentry hasn't finished loading yet (or telemetry is disabled), this is
|
|
26
|
+
* exactly a plain fetch() with no added delay.
|
|
27
|
+
*/
|
|
28
|
+
export declare function instrumentedFetch(name: string, url: string, init?: RequestInit): Promise<Response>;
|