@glomex/integration-web-component 1.1297.1

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/README.md ADDED
@@ -0,0 +1,71 @@
1
+ # @glomex/integration-web-component
2
+
3
+ ## Introduction
4
+
5
+ `@glomex/integration-web-component` exposes a Web Component and types to easily integrate the glomex player. In order to use this component, you need to have a glomex account. You can get one by following the instructions in the [Getting Started](https://docs.glomex.com/publisher/getting-started) section.
6
+
7
+ ## About glomex
8
+
9
+ [glomex](https://glomex.com) operates Germany’s largest marketplace for premium video content. Our platform connects publishers, content creators, and advertisers, enabling the seamless distribution of high-quality video content across the web.
10
+
11
+ Our ecosystem is designed to create value for all participants:
12
+
13
+ - **Publishers** gain access to premium video content and monetization opportunities
14
+ - **Content Owners** receive wide distribution and revenue for their video assets
15
+ - **Advertisers** reach targeted audiences across a network of quality websites
16
+
17
+ ## Usage
18
+
19
+ ### Loading & integrating the player
20
+
21
+ For plain JavaScript projects, you can follow [this guide](https://docs.glomex.com/publisher/player/embed-code/advanced/javascript).
22
+ You though can use the `@glomex/integration-web-component` helper to load the integration component and styles also in JavaScript projects.
23
+
24
+ ```ts
25
+ import {
26
+ IntegrationEvent,
27
+ ComponentName,
28
+ loadIntegrationComponent,
29
+ loadIntegrationStyles
30
+ } from '@glomex/integration-web-component';
31
+
32
+ // Get the container element where the player will be placed
33
+ const container = document.getElementById('player-container-on-site');
34
+ const integrationId = 'FILL_IN_INTEGRATION_ID';
35
+ const playlistId = 'FILL_IN_PLAYLIST_ID';
36
+ // It makes sense to load integration css
37
+ // as early as possible to reduce layout shifts.
38
+ // You also can get the CSS URL with this helper:
39
+ // `import { getIntegrationCssUrl } from '@glomex/integration/load';`
40
+ loadIntegrationStyles(integrationId);
41
+ // load the integration web component
42
+ loadIntegrationComponent();
43
+ // create the fully typed integration element
44
+ const integration = document.createElement(ComponentName.INTEGRATION);
45
+ integration.setAttribute('integration-id', integrationId);
46
+ integration.setAttribute('playlist-id', playlistId);
47
+ integration.addEventListener(IntegrationEvent.CONTENT_START, () => {
48
+ console.log('content start', integration.content);
49
+ });
50
+ // attach the integration element
51
+ container.appendChild(integration);
52
+ // wait until the integration was upgraded to access web component methods
53
+ await window.customElements.whenDefined(ComponentName.INTEGRATION);
54
+ integration.play();
55
+ ```
56
+
57
+ ### Implementing a public API script
58
+
59
+ ```ts
60
+ import {
61
+ IntegrationEvent,
62
+ type ConnectIntegration
63
+ } from '@glomex/integration-web-component';
64
+
65
+ // with this you get a fully typed integration
66
+ export const connectIntegration: ConnectIntegration = (integration) => {
67
+ integration.addEventListener(IntegrationEvent.CONTENT_PLAY, () => {
68
+ console.log('play', integration.content);
69
+ });
70
+ };
71
+ ```
@@ -0,0 +1,1044 @@
1
+
2
+
3
+ export declare interface Ad {
4
+ id: string;
5
+ isLinear: boolean;
6
+ duration: number;
7
+ positionIndex: number;
8
+ breakIndex: number;
9
+ breakName: string;
10
+ mimetype: string;
11
+ nonLinearWidth?: number;
12
+ nonLinearHeight?: number;
13
+ }
14
+
15
+ export declare interface Channel {
16
+ /** Name of the channel */
17
+ name: string;
18
+ /** Identifier of the channel */
19
+ id?: string;
20
+ /** Target URL of the channel */
21
+ url?: string;
22
+ /** Square logo of the channel (optimal size: 96x96 pixels) */
23
+ logo?: string;
24
+ }
25
+
26
+ export declare enum ComponentName {
27
+ INTEGRATION = "glomex-integration",
28
+ EXTERNAL_MEDIA_ITEM = "glomex-external-media-item",
29
+ GLOMEX_MEDIA_ITEM = "glomex-media-item"
30
+ }
31
+
32
+ export declare interface Consent {
33
+ gdprApplies: boolean;
34
+ consentString?: string;
35
+ cmpId?: number;
36
+ policyVersion?: number;
37
+ vendorListVersion?: number;
38
+ vendorConsents?: Record<string, boolean>;
39
+ vendorLegitimateInterests?: Record<string, boolean>;
40
+ purposeConsents?: Record<string, boolean>;
41
+ purposeLegitimateInterests?: Record<string, boolean>;
42
+ ready: boolean;
43
+ addtlConsent?: string;
44
+ }
45
+
46
+ export declare interface CustomMarker {
47
+ /** {@inheritDoc Marker.name} */
48
+ name: string;
49
+ /** {@inheritDoc Marker.type} */
50
+ type: MarkerType;
51
+ /** {@inheritDoc Marker.threshold} */
52
+ threshold: number;
53
+ }
54
+
55
+ declare interface Experiment {
56
+ name: string;
57
+ enabled: boolean;
58
+ participantPercentage: number;
59
+ variants: Record<string, ExperimentVariant>;
60
+ conditions: Record<string, unknown>;
61
+ }
62
+
63
+ declare interface ExperimentVariant {
64
+ weight: number;
65
+ contentOverride: Record<string, unknown>;
66
+ }
67
+
68
+ /**
69
+ * A media item web component that allows to define an external media item. It can be placed
70
+ * inside the integration element. For more complex use cases, see {@link MediaItemElement}.
71
+ *
72
+ * @tagname glomex-external-media-item
73
+ *
74
+ * @slot - (optional) Slot for inline JSON of type `application/glomex-external-media-item+json`
75
+ *
76
+ * @example the most simple glomex-external-media-item
77
+ *
78
+ * This only works when no `playlist-id` is assigned to `glomex-integration`
79
+ *
80
+ * ```html
81
+ * <glomex-integration
82
+ * integration-id="REPLACE_WITH_INTEGRATION_ID"
83
+ * >
84
+ * <glomex-external-media-item
85
+ * id="SOME_ID"
86
+ * src="SOME_VIDEO_URL"
87
+ * duration="LENGTH_OF_VIDEO"
88
+ * poster="POSTER_URL"
89
+ * title="VIDEO_TITLE"
90
+ * ></glomex-external-media-item>
91
+ * <!-- further media items -->
92
+ * </glomex-integration>
93
+ * ```
94
+ *
95
+ * @example the most simple glomex-external-media-item with inline JSON
96
+ *
97
+ * It is possible to use {@link MediaItem}, {@link MinimalMediaItem}, or array of {@link MediaItem} or {@link MinimalMediaItem}
98
+ * in JSON format.
99
+ *
100
+ * ```html
101
+ * <glomex-integration
102
+ * integration-id="REPLACE_WITH_INTEGRATION_ID"
103
+ * >
104
+ * <glomex-external-media-item>
105
+ * <script type="application/glomex-external-media-item+json">
106
+ * {
107
+ * "id": "SOME_ID",
108
+ * "sources": [
109
+ * {
110
+ * "src": "SOME_VIDEO_URL",
111
+ * "mimetype": "video/mp4"
112
+ * }
113
+ * ],
114
+ * "duration": "LENGTH_OF_VIDEO",
115
+ * "poster": "POSTER_URL",
116
+ * "title": "VIDEO_TITLE"
117
+ * }
118
+ * </script>
119
+ * </glomex-external-media-item>
120
+ * </glomex-integration>
121
+ * ```
122
+ */
123
+ export declare class ExternalMediaItemElement extends HTMLElement implements MediaItemElement {
124
+ #private;
125
+ /**
126
+ * {@inheritDoc MediaItem#id}
127
+ */
128
+ id: string;
129
+ /**
130
+ * {@inheritDoc MediaSource#src}
131
+ */
132
+ src: string;
133
+ /**
134
+ * {@inheritDoc MediaSource#mimetype}
135
+ */
136
+ mimetype?: MediaSource_2['mimetype'];
137
+ /**
138
+ * {@inheritDoc MediaItem#type}
139
+ */
140
+ type?: MediaItem['type'];
141
+ /**
142
+ * {@inheritDoc MediaItem#duration}
143
+ */
144
+ duration?: number;
145
+ /**
146
+ * {@inheritDoc MediaItem#poster}
147
+ */
148
+ poster: string;
149
+ /**
150
+ * {@inheritDoc MediaItem#title}
151
+ */
152
+ title: string;
153
+ /**
154
+ * {@inheritDoc MediaItem#description}
155
+ */
156
+ description?: string;
157
+ /**
158
+ * {@inheritDoc Channel#logo}
159
+ */
160
+ channelLogo?: string;
161
+ /**
162
+ * {@inheritDoc Channel#name}
163
+ */
164
+ channelName?: string;
165
+ /**
166
+ * {@inheritDoc MediaItem#aspectRatio}
167
+ */
168
+ aspectRatio?: string;
169
+ /**
170
+ * {@inheritDoc MediaItem#minimumAge}
171
+ */
172
+ minimumAge?: number;
173
+ /**
174
+ * {@inheritDoc MediaItem#releaseDate}
175
+ */
176
+ releaseDate?: number;
177
+ /**
178
+ * {@inheritDoc MediaItem#endDate}
179
+ */
180
+ endDate?: number;
181
+ /**
182
+ * {@inheritDoc MediaItem#hasProductPlacement}
183
+ */
184
+ hasProductPlacement?: boolean;
185
+ get data(): MinimalMediaItem | MediaItem;
186
+ }
187
+
188
+ export declare function getIntegrationCssUrl(integrationId: string): string;
189
+
190
+ /**
191
+ * Web component that allows to override title and poster of a given glomex content id. It can be placed
192
+ * inside the integration element. For integrating external media items, see {@link ExternalMediaItemElement}.
193
+ *
194
+ * @tagname glomex-media-item
195
+ *
196
+ * @example with 2 glomex-media-items
197
+ *
198
+ * This only works when no `playlist-id` is assigned to `glomex-integration`
199
+ *
200
+ * ```html
201
+ * <glomex-integration
202
+ * integration-id="REPLACE_WITH_INTEGRATION_ID"
203
+ * >
204
+ * <glomex-media-item
205
+ * id="REPLACE_WITH_MEDIA_OR_PLAYLIST_ID"
206
+ * ></glomex-media-item>
207
+ * <glomex-media-item
208
+ * id="ANOTHER_MEDIA_OR_PLAYLIST_ID"
209
+ * ></glomex-media-item>
210
+ * </glomex-integration>
211
+ * ```
212
+ *
213
+ * @example glomex-media-item with title and poster override
214
+ *
215
+ * ```html
216
+ * <glomex-integration
217
+ * integration-id="REPLACE_WITH_INTEGRATION_ID"
218
+ * >
219
+ * <glomex-media-item
220
+ * id="REPLACE_WITH_MEDIA_OR_PLAYLIST_ID"
221
+ * title="REPLACE_WITH_TITLE_OVERRIDE"
222
+ * poster="REPLACE_WITH_POSTER_URL_OVERRIDE"
223
+ * ></glomex-media-item>
224
+ * </glomex-integration>
225
+ * ```
226
+ */
227
+ export declare class GlomexMediaItemElement extends HTMLElement {
228
+ /**
229
+ * {@inheritDoc MediaItem#id}
230
+ */
231
+ id: string;
232
+ /**
233
+ * Overridden poster of the media item.
234
+ */
235
+ poster?: string;
236
+ /**
237
+ * Overridden title of the media item.
238
+ */
239
+ title: string;
240
+ }
241
+
242
+ /**
243
+ * Web component to integrate the player.
244
+ *
245
+ * @see {@link IntegrationElementEventMap} for a full list of event types and their payloads
246
+ * @tagname glomex-integration
247
+ * @slot - (optional) Slot for custom media items ({@link GlomexMediaItemElement}, {@link ExternalMediaItemElement} or {@link MediaItemElement})
248
+ *
249
+ * @example with a playlist-id
250
+ *
251
+ * ```html
252
+ * <glomex-integration
253
+ * integration-id="REPLACE_WITH_INTEGRATION_ID"
254
+ * playlist-id="REPLACE_WITH_PLAYLIST_ID"
255
+ * ></glomex-integration>
256
+ * ```
257
+ *
258
+ * You can find more advanced examples in the {@link GlomexMediaItemElement}, {@link ExternalMediaItemElement} or {@link MediaItemElement} documentation.
259
+ */
260
+ export declare class IntegrationElement extends HTMLElement implements IntegrationProperties {
261
+ #private;
262
+ static MarkerType: typeof MarkerType;
263
+ static KnownMarkerName: typeof KnownMarkerName;
264
+ static StreamType: typeof StreamType;
265
+ static Mimetype: typeof Mimetype;
266
+ static PresentationMode: typeof PresentationMode;
267
+ static IntegrationEvent: typeof IntegrationEvent;
268
+ /**
269
+ * {@inheritDoc IntegrationProperties.integrationId}
270
+ * @attribute integration-id
271
+ */
272
+ integrationId?: string;
273
+ /**
274
+ * {@inheritDoc IntegrationProperties.playlistId}
275
+ * @attribute playlist-id
276
+ */
277
+ playlistId?: string;
278
+ /**
279
+ * {@inheritDoc IntegrationProperties.index}
280
+ * @attribute index
281
+ */
282
+ index?: number;
283
+ /**
284
+ * {@inheritDoc IntegrationProperties.hidden}
285
+ * @attribute {on|off} hidden
286
+ */
287
+ hidden: boolean;
288
+ /**
289
+ * {@inheritDoc IntegrationProperties.topLevelIframe}
290
+ * @attribute top-level-iframe
291
+ */
292
+ topLevelIframe: boolean;
293
+ /**
294
+ * {@inheritDoc IntegrationProperties.placement}
295
+ * @attribute placement
296
+ */
297
+ placement?: string;
298
+ /**
299
+ * Initiates playback of the media content.
300
+ */
301
+ play(): void;
302
+ /**
303
+ * Pauses the current media playback.
304
+ */
305
+ pause(): void;
306
+ /**
307
+ * Returns the current playback time (in seconds) of the media.
308
+ */
309
+ get currentTime(): number;
310
+ /**
311
+ * Returns the current wall clock time (UNIX timestamp in seconds). Useful for livestreams.
312
+ */
313
+ get wallClockTime(): number;
314
+ /**
315
+ * Seeks the media to the specified time, updating the current playback time.
316
+ * @param time - The time (in seconds) to seek to.
317
+ */
318
+ set currentTime(time: number);
319
+ /**
320
+ * Retrieves the total duration (in seconds) of the current media content.
321
+ */
322
+ get duration(): number;
323
+ /**
324
+ * Indicates whether the media playback is currently muted.
325
+ */
326
+ get muted(): boolean;
327
+ /**
328
+ * Mutes or unmutes the media playback.
329
+ * @param value - A boolean value indicating whether to mute the media playback.
330
+ */
331
+ set muted(value: boolean);
332
+ /**
333
+ * Returns the current volume level of the media playback (0-1).
334
+ */
335
+ get volume(): number;
336
+ /**
337
+ * Sets the media playback volume to the specified level.
338
+ * @param value - The volume level to be set (0-1).
339
+ */
340
+ set volume(value: number);
341
+ /**
342
+ * Returns `true` if the media playback is currently paused; otherwise, returns `false`.
343
+ */
344
+ get paused(): boolean;
345
+ /**
346
+ * Indicates whether the media is currently in a seeking state.
347
+ */
348
+ get seeking(): boolean;
349
+ /**
350
+ * Retrieves the current presentation mode of the media player.
351
+ * This mode may affect how the media is displayed.
352
+ */
353
+ get presentationMode(): PresentationMode;
354
+ /**
355
+ * Returns whether the ad playback is muted. If no ad is currently active, this value is `undefined`.
356
+ */
357
+ get adMuted(): boolean | undefined;
358
+ /**
359
+ * Retrieves the volume level for the ad playback. If no ad is currently active, this value is `undefined`.
360
+ */
361
+ get adVolume(): number | undefined;
362
+ /**
363
+ * Returns the current playback time (in seconds) for the ad content. If no ad is currently active, this value is `NaN`.
364
+ */
365
+ get adCurrentTime(): number;
366
+ /**
367
+ * Retrieves the total duration (in seconds) of the ad content. If no ad is currently active, this value is `NaN`.
368
+ */
369
+ get adDuration(): number;
370
+ /**
371
+ * Indicates whether the ad playback is currently paused. If no ad is currently active, this value is `undefined`.
372
+ */
373
+ get adPaused(): boolean | undefined;
374
+ /**
375
+ * Retrieves the currently selected content item.
376
+ */
377
+ get content(): MediaItem | undefined;
378
+ /**
379
+ * Retrieves the current playlist content items.
380
+ */
381
+ get playlist(): MediaItem[] | undefined;
382
+ /**
383
+ * Provides access to the user's consent information.
384
+ */
385
+ get consent(): Consent | undefined;
386
+ /**
387
+ * Retrieves information about the detected page.
388
+ */
389
+ get page(): Page | undefined;
390
+ /**
391
+ * Retrieves the playback time (in seconds) of the current content.
392
+ */
393
+ get contentPlaybackTime(): number;
394
+ /**
395
+ * Retrieves details about the currently selected ad, if any.
396
+ */
397
+ get currentAd(): Ad | undefined;
398
+ /**
399
+ * Sets the presentation mode of the media player to the specified mode. This mode affects how the integration gets displayed
400
+ * (e.g. inline, dock, lightbox, fullscreen).
401
+ *
402
+ * @param {PresentationMode} mode - The presentation mode to set.
403
+ * @param {Object} [options] - Optional configuration.
404
+ * @param {boolean} [options.byUser=false] - Indicates if the change was initiated by a user action.
405
+ */
406
+ setPresentationMode(mode: PresentationMode | PresentationModeString, { byUser }?: {
407
+ byUser?: boolean | undefined;
408
+ }): void;
409
+ /**
410
+ * Exits the current presentation mode.
411
+ *
412
+ * @param {Object} [options] - Optional configuration.
413
+ * @param {boolean} [options.byUser=false] - Indicates if the change was initiated by a user action.
414
+ */
415
+ exitCurrentPresentationMode({ byUser }?: {
416
+ byUser?: boolean;
417
+ }): void;
418
+ }
419
+
420
+ /**
421
+ * Map of events that are dispatched by the {@link IntegrationElement}. The {@link IntegrationElement} provides
422
+ * getters to read {@link IntegrationElement#consent consent}, {@link IntegrationElement#content content}, {@link IntegrationElement#page page}, {@link IntegrationElement#currentTime currentTime}, ... state from.
423
+ *
424
+ * @see {@link IntegrationEvent} for all event types as constants
425
+ *
426
+ * @example
427
+ *
428
+ * ```js
429
+ * // using strings
430
+ * integration.addEventListener('ready', () => {});
431
+ * // using constants
432
+ * await window.customElements.whenDefined('glomex-integration');
433
+ * const { IntegrationEvent } = integration.constructor;
434
+ * integration.addEventListener(IntegrationEvent.READY, () => {});
435
+ * ```
436
+ */
437
+ export declare interface IntegrationElementEventMap {
438
+ /** @eventProperty */
439
+ ready: CustomEvent<unknown>;
440
+ /** @eventProperty */
441
+ integrationabort: CustomEvent<unknown & {
442
+ error: Error;
443
+ }>;
444
+ /** @eventProperty */
445
+ integrationadavailable: CustomEvent<unknown>;
446
+ /** @eventProperty */
447
+ integrationpassback: CustomEvent<unknown & {
448
+ reason: string;
449
+ }>;
450
+ /** @eventProperty */
451
+ userupdateconsent: CustomEvent<unknown>;
452
+ /** @eventProperty */
453
+ playlistupdate: CustomEvent<unknown>;
454
+ /** @eventProperty */
455
+ playersetpresentationmode: CustomEvent<unknown & {
456
+ mode: PresentationMode;
457
+ }>;
458
+ /** @eventProperty */
459
+ contentstart: CustomEvent<unknown>;
460
+ /** @eventProperty */
461
+ contentimpression: CustomEvent<unknown>;
462
+ /** @eventProperty */
463
+ contentstop: CustomEvent<unknown>;
464
+ /** @eventProperty */
465
+ contenterror: CustomEvent<unknown & {
466
+ error: MediaError_2 | MediaItemError;
467
+ }>;
468
+ /** @eventProperty */
469
+ contentmarkerreached: CustomEvent<unknown & {
470
+ markerName: string;
471
+ markerData: unknown;
472
+ }>;
473
+ /** @eventProperty */
474
+ timeupdate: CustomEvent<unknown> | HTMLElementEventMap['timeupdate'];
475
+ /** @eventProperty */
476
+ seeking: CustomEvent<unknown> | HTMLElementEventMap['seeking'];
477
+ /** @eventProperty */
478
+ seeked: CustomEvent<unknown> | HTMLElementEventMap['seeked'];
479
+ /** @eventProperty */
480
+ play: CustomEvent<unknown> | HTMLElementEventMap['play'];
481
+ /** @eventProperty */
482
+ pause: CustomEvent<unknown> | HTMLElementEventMap['pause'];
483
+ /** @eventProperty */
484
+ volumechange: CustomEvent<unknown> | HTMLElementEventMap['volumechange'];
485
+ /** @eventProperty */
486
+ ended: CustomEvent<unknown> | HTMLElementEventMap['ended'];
487
+ /** @eventProperty */
488
+ adimpression: CustomEvent<unknown>;
489
+ /** @eventProperty */
490
+ adtimeupdate: CustomEvent<unknown>;
491
+ /** @eventProperty */
492
+ advolumechange: CustomEvent<unknown>;
493
+ /** @eventProperty */
494
+ adpaused: CustomEvent<unknown>;
495
+ /** @eventProperty */
496
+ adresumed: CustomEvent<unknown>;
497
+ /** @eventProperty */
498
+ adclick: CustomEvent<unknown>;
499
+ /** @eventProperty */
500
+ adskipped: CustomEvent<unknown>;
501
+ /** @eventProperty */
502
+ adcomplete: CustomEvent<unknown>;
503
+ }
504
+
505
+ /**
506
+ * Constants for all events dispatched by the {@link IntegrationElement}.
507
+ *
508
+ * @see {@link IntegrationElementEventMap} for a full list of event types and their payloads
509
+ */
510
+ export declare enum IntegrationEvent {
511
+ /** @eventProperty */
512
+ READY = "ready",
513
+ /** @eventProperty */
514
+ INTEGRATION_ABORT = "integrationabort",
515
+ /** @eventProperty */
516
+ INTEGRATION_AD_AVAILABLE = "integrationadavailable",
517
+ /** @eventProperty */
518
+ INTEGRATION_PASSBACK = "integrationpassback",
519
+ /** @eventProperty */
520
+ USER_UPDATE_CONSENT = "userupdateconsent",
521
+ /** @eventProperty */
522
+ PLAYLIST_UPDATE = "playlistupdate",
523
+ /** @eventProperty */
524
+ PLAYER_SET_PRESENTATION_MODE = "playersetpresentationmode",
525
+ /** @eventProperty */
526
+ CONTENT_START = "contentstart",
527
+ /** @eventProperty */
528
+ CONTENT_IMPRESSION = "contentimpression",
529
+ /** @eventProperty */
530
+ CONTENT_STOP = "contentstop",
531
+ /** @eventProperty */
532
+ CONTENT_ERROR = "contenterror",
533
+ /** @eventProperty */
534
+ CONTENT_MARKER_REACHED = "contentmarkerreached",
535
+ /** @eventProperty */
536
+ CONTENT_TIME_UPDATE = "timeupdate",
537
+ /** @eventProperty */
538
+ CONTENT_SEEKING = "seeking",
539
+ /** @eventProperty */
540
+ CONTENT_SEEKED = "seeked",
541
+ /** @eventProperty */
542
+ CONTENT_PLAY = "play",
543
+ /** @eventProperty */
544
+ CONTENT_PAUSE = "pause",
545
+ /** @eventProperty */
546
+ CONTENT_VOLUME_CHANGE = "volumechange",
547
+ /** @eventProperty */
548
+ CONTENT_ENDED = "ended",
549
+ /** @eventProperty */
550
+ AD_IMPRESSION = "adimpression",
551
+ /** @eventProperty */
552
+ AD_TIME_UPDATE = "adtimeupdate",
553
+ /** @eventProperty */
554
+ AD_VOLUME_CHANGE = "advolumechange",
555
+ /** @eventProperty */
556
+ AD_PAUSED = "adpaused",
557
+ /** @eventProperty */
558
+ AD_RESUMED = "adresumed",
559
+ /** @eventProperty */
560
+ AD_CLICK = "adclick",
561
+ /** @eventProperty */
562
+ AD_SKIPPED = "adskipped",
563
+ /** @eventProperty */
564
+ AD_COMPLETE = "adcomplete"
565
+ }
566
+
567
+ /**
568
+ * Properties that can be set on the integration element.
569
+ */
570
+ export declare interface IntegrationProperties {
571
+ /**
572
+ * The identifier for this integration. This value is used to determine the configuration and behavior of the integration.
573
+ */
574
+ integrationId?: string;
575
+ /**
576
+ * Defines the playlist / content identifier that should be loaded and managed by the integration. It can be a single content id, a playlist id or `auto`.
577
+ * It must be empty when the content is provided via the `media-item` web components inside the integration.
578
+ */
579
+ playlistId?: string;
580
+ /**
581
+ * Determines the index of the media item within the playlist that should be or is currently selected.
582
+ */
583
+ index?: number;
584
+ /**
585
+ * Hides the integration element when set to `true`.
586
+ */
587
+ hidden?: boolean;
588
+ /**
589
+ * An optional flag that can mark the integration as if it is running in a top-level window context. Useful when the embedded iframe represents an article, which contains this integration.
590
+ */
591
+ topLevelIframe?: boolean;
592
+ /**
593
+ * Allows the publisher to provide an optional placement attribute, which supplies additional contextual information for enhanced analytics tracking.
594
+ */
595
+ placement?: string;
596
+ }
597
+
598
+ export declare enum KnownMarkerName {
599
+ PREROLL = "preroll",
600
+ MIDROLL = "midroll",
601
+ POSTROLL = "postroll",
602
+ FIRST_QUARTILE = "contentFirstQuartile",
603
+ MIDPOINT = "contentMidpoint",
604
+ THIRD_QUARTILE = "contentThirdQuartile",
605
+ COMPLETE = "contentComplete",
606
+ STILL_INTERESTING = "stillInteresting"
607
+ }
608
+
609
+ export declare function loadIntegrationComponent(): Promise<unknown>;
610
+
611
+ export declare function loadIntegrationStyles(integrationId: string): void;
612
+
613
+ /**
614
+ * Known markers that the integration interprets.
615
+ */
616
+ export declare interface Marker {
617
+ /** Name of the marker */
618
+ name: KnownMarkerName;
619
+ /** Type of the marker */
620
+ type: MarkerType;
621
+ /**
622
+ * Threshold for the marker:
623
+ * - {@link MarkerType.TIME_IN_SECONDS}: seconds
624
+ * - {@link MarkerType.PERCENT}: percent as fraction (0-1)
625
+ * - {@link MarkerType.TIME_IN_SECONDS_RECURRING}: seconds
626
+ */
627
+ threshold: number;
628
+ }
629
+
630
+ export declare enum MarkerType {
631
+ /** Triggers by time in seconds */
632
+ TIME_IN_SECONDS = "time",
633
+ /** Triggers by percentage (only works when media item has a {@link MediaItem#duration duration}) */
634
+ PERCENT = "percent",
635
+ /** Recurringly triggers by time in seconds (e.g. every 60 seconds) */
636
+ TIME_IN_SECONDS_RECURRING = "timeRecurring"
637
+ }
638
+
639
+ /**
640
+ * Runtime error when the player fails to load or play a media item.
641
+ */
642
+ declare interface MediaError_2 {
643
+ name: 'MediaError';
644
+ /** Error code from the playback engine */
645
+ code: string;
646
+ /** A detailed error message */
647
+ message: string;
648
+ }
649
+ export { MediaError_2 as MediaError }
650
+
651
+ export declare interface MediaItem extends MinimalMediaItem {
652
+ /** @ignore */
653
+ ppsj: string;
654
+ /**
655
+ * Mark this media item as a recommendation.
656
+ */
657
+ isRecommendation?: boolean;
658
+ /** @ignore */
659
+ playlistId: string;
660
+ /**
661
+ * JSON-LD `contentUrl` that allows search engines to crawl the media source.
662
+ * You should only allow known crawlers ({@link https://developers.google.com/search/docs/crawling-indexing/verifying-googlebot?hl=en how to verify Googlebot & Crawler})
663
+ * to access those media sources.
664
+ */
665
+ seoContentUrl?: string;
666
+ /**
667
+ * Additional teaser options.
668
+ */
669
+ teaser?: {
670
+ /** Image of the first frame of the media item. Used for initially showing the first frame of the media item. */
671
+ firstFrame?: string;
672
+ /** {@link https://blurha.sh/ Blurhash} of the first frame of the media item. Used for coloring the background. */
673
+ firstFrameBlurHash?: string | null;
674
+ /** Blurred version of the first frame of the media item. Used to show something early while loading. */
675
+ firstFrameBlurred?: string;
676
+ /**
677
+ * The root `poster` is used
678
+ * @ignore
679
+ */
680
+ poster?: string;
681
+ /** {@link https://blurha.sh/ Blurhash} of the poster of the media item. Used for coloring the background. */
682
+ posterBlurHash?: string | null;
683
+ /** Blurred version of the poster of the media item. Used to show something early while loading. */
684
+ posterBlurred?: string;
685
+ /**
686
+ * Can probably be removed because unused.
687
+ * @ignore
688
+ */
689
+ thumbnail?: string;
690
+ /** Teaser video URL which is used for previewing the media item for some integrations. */
691
+ video?: string;
692
+ /**
693
+ * The root `title` is used
694
+ *
695
+ * @ignore
696
+ */
697
+ title?: string;
698
+ };
699
+ /** @ignore */
700
+ labels?: {
701
+ id: string;
702
+ name: string;
703
+ }[];
704
+ /** Genre of the media item (e.g. `Documentary`) */
705
+ genre?: string;
706
+ /** Content owner id and name of the media item */
707
+ contentOwner?: {
708
+ id?: string;
709
+ name: string;
710
+ };
711
+ /**
712
+ * Details to show for the age rating (e.g. `['Alcohol']`)
713
+ */
714
+ ageRatingDetails?: string[];
715
+ /** Keywords of the media item */
716
+ keywords?: string[];
717
+ /** Show id and name of the media item */
718
+ show?: {
719
+ name: string;
720
+ id?: string;
721
+ };
722
+ /** Category id and name of the media item */
723
+ category?: {
724
+ name: string;
725
+ id?: string;
726
+ };
727
+ error?: MediaItemError;
728
+ /** @ignore */
729
+ experiments?: Experiment[];
730
+ /** @ignore */
731
+ branding?: {
732
+ backgroundColor?: string;
733
+ cutInZoomAssetUrl?: string;
734
+ cutInZoomHideTimeout?: number;
735
+ logoUrl?: string;
736
+ logoLinkUrl?: string;
737
+ };
738
+ /** @ignore */
739
+ tracking?: {
740
+ scriptUrl: string;
741
+ data?: {
742
+ episodeExternalId?: string;
743
+ showTitle?: string;
744
+ showId?: string;
745
+ onlineExclusive?: boolean;
746
+ channel?: string;
747
+ };
748
+ };
749
+ /** Livestream details */
750
+ livestream?: {
751
+ /** UTC start time of the livestream in milliseconds */
752
+ startTime: number;
753
+ /** UTC end time of the livestream in milliseconds */
754
+ endTime?: number;
755
+ };
756
+ /** @ignore */
757
+ allowTeaserExperiments: boolean;
758
+ /**
759
+ * URL of the API script that should be executed for this media-item. Script
760
+ * must export `export function connectIntegration(glomexIntegration) {}`
761
+ *
762
+ * @ignore
763
+ */
764
+ apiScriptUrl?: string;
765
+ /**
766
+ * An external episode identifier. Often the id the episode was imported from.
767
+ */
768
+ externalEpisodeId?: string;
769
+ /**
770
+ * An additional external show name. Often the name the show was imported from.
771
+ */
772
+ externalShowName?: string;
773
+ /**
774
+ * An additional external show identifier. Often the id the show was imported from.
775
+ */
776
+ externalShowId?: string;
777
+ /**
778
+ * An additional external channel name. Often the name the channel was imported from.
779
+ */
780
+ externalChannelName?: string;
781
+ /**
782
+ * Whether the media item is exclusive for the web.
783
+ */
784
+ isWebExclusive?: boolean;
785
+ }
786
+
787
+ /**
788
+ * Abstract definition of a media item web component that can be used as a child of the {@link IntegrationElement}.
789
+ *
790
+ * @example of a custom media item
791
+ *
792
+ * It is possible to create more complex media items that query an own API.
793
+ *
794
+ * ```html
795
+ * <script>
796
+ * class CustomMediaItemElement extends HTMLElement {
797
+ * get data() {
798
+ * return fetch(`https://api.example.com/media/${this.getAttribute('id')}`)
799
+ * .then(response => response.json())
800
+ * .then((body) => ({
801
+ * id: this.getAttribute('id'),
802
+ * sources: body.sources,
803
+ * duration: body.duration,
804
+ * poster: body.poster,
805
+ * title: body.title
806
+ * }));
807
+ * }
808
+ * }
809
+ * window.customElements.define('custom-media-item', CustomMediaItemElement);
810
+ * </script>
811
+ * <glomex-integration
812
+ * integration-id="REPLACE_WITH_INTEGRATION_ID"
813
+ * >
814
+ * <custom-media-item id="API_CONTENT_ID"></custom-media-item>
815
+ * </glomex-integration>
816
+ * ```
817
+ */
818
+ export declare interface MediaItemElement extends HTMLElement {
819
+ readonly data: MediaItem | MinimalMediaItem | (MediaItem | MinimalMediaItem)[] | Promise<MediaItem | MinimalMediaItem | (MediaItem | MinimalMediaItem)[]>;
820
+ }
821
+
822
+ /**
823
+ * Serializable error with the reason why a media item is not available.
824
+ * `name` is set to `MediaItemError` internally.
825
+ */
826
+ export declare interface MediaItemError {
827
+ /**
828
+ * @protected
829
+ */
830
+ name?: 'MediaItemError';
831
+ /** Error code that gets handled by the player */
832
+ code: MediaItemErrorCode;
833
+ /** Optional custom error message or code from the source system */
834
+ message?: string;
835
+ }
836
+
837
+ export declare enum MediaItemErrorCode {
838
+ NOT_FOUND = "NotFound",
839
+ NOT_AVAILABLE = "NotAvailable",
840
+ GEOBLOCKED = "Geoblocked",
841
+ YOUTH_PROTECTED = "YouthProtected"
842
+ }
843
+
844
+ declare interface MediaSource_2 {
845
+ /**
846
+ * Unique identifier of the media source.
847
+ *
848
+ * @defaultValue `...` a generated identifier
849
+ */
850
+ id?: string;
851
+ /**
852
+ * Mimetype of the media source.
853
+ *
854
+ * @defaultValue detected from file extension of given {@link src} or `undefined`
855
+ */
856
+ mimetype?: Mimetype;
857
+ /**
858
+ * The source URL of this media source.
859
+ */
860
+ src: string;
861
+ /**
862
+ * Until the media source is valid. Unix timestamp in milliseconds.
863
+ */
864
+ validUntil?: number;
865
+ /**
866
+ * DRM provider header name. Only relevant in combination with tokens.
867
+ */
868
+ drmProviderHeaderName?: string;
869
+ /**
870
+ * Fairplay license URI. Or `undefined` when {@link fairplayToken} in combination with {@link drmProviderHeaderName} is provided.
871
+ */
872
+ fairplayLicenseUri?: string;
873
+ /**
874
+ * FairPlay certificate URI.
875
+ */
876
+ fairplayCertificateUri?: string;
877
+ /**
878
+ * FairPlay token.
879
+ */
880
+ fairplayToken?: string;
881
+ /**
882
+ * Widevine license URI. Or `undefined` when {@link widevineToken} in combination with {@link drmProviderHeaderName} is provided.
883
+ */
884
+ widevineLicenseUri?: string;
885
+ /**
886
+ * Widevine token.
887
+ */
888
+ widevineToken?: string;
889
+ /**
890
+ * PlayReady license URI. Or `undefined` when {@link playreadyToken} in combination with {@link drmProviderHeaderName} is provided.
891
+ */
892
+ playreadyLicenseUri?: string;
893
+ /**
894
+ * PlayReady token.
895
+ */
896
+ playreadyToken?: string;
897
+ }
898
+ export { MediaSource_2 as MediaSource }
899
+
900
+ export declare enum Mimetype {
901
+ HLS = "application/vnd.apple.mpegurl",
902
+ HLS_LEGACY = "application/x-mpegURL",
903
+ DASH = "application/dash+xml",
904
+ MP4 = "video/mp4",
905
+ OGG = "video/ogg",
906
+ WEBM = "video/webm",
907
+ MP3 = "audio/mp3",
908
+ AAC = "audio/aac",
909
+ WAV = "audio/wav",
910
+ OGG_AUDIO = "audio/ogg",
911
+ MPEG_AUDIO = "audio/mpeg",
912
+ DYNAMIC_CONTENT = "application/x-turbo-dynamic-content"
913
+ }
914
+
915
+ export declare interface MinimalMediaItem {
916
+ /**
917
+ * Unique identifier of the media item.
918
+ */
919
+ id: string;
920
+ /**
921
+ * Poster image of the media item.
922
+ */
923
+ poster: string;
924
+ /**
925
+ * Sources of the media item.
926
+ */
927
+ sources: MediaSource_2[];
928
+ /**
929
+ * Title of the media item.
930
+ */
931
+ title: string;
932
+ /**
933
+ * Duration of the media item in seconds. Not defined when livestream.
934
+ */
935
+ duration?: number;
936
+ /**
937
+ * Description of the media item.
938
+ */
939
+ description?: string;
940
+ /**
941
+ * Stream type of the media item.
942
+ *
943
+ * @defaultValue `StreamType.VOD`
944
+ */
945
+ type?: StreamType;
946
+ /**
947
+ * Language of the media item. 2-letter ISO language code.
948
+ *
949
+ * @defaultValue `de` (German)
950
+ */
951
+ language?: string;
952
+ /**
953
+ * IAB categories (as {@link iabCategoryTaxonomy}) of the media item.
954
+ */
955
+ iabCategories?: string[];
956
+ /**
957
+ * IAB category taxonomy used for {@link iabCategories} ({@link https://github.com/InteractiveAdvertisingBureau/AdCOM/blob/main/AdCOM%20v1.0%20FINAL.md#list_categorytaxonomies see IAB spec for details})
958
+ * @defaultValue `9` for IAB Tech Lab Content Taxonomy 3.1
959
+ */
960
+ iabCategoryTaxonomy?: number;
961
+ /**
962
+ * Aspect ratio of the media item.
963
+ *
964
+ * @defaultValue `16:9`
965
+ */
966
+ aspectRatio?: string;
967
+ /**
968
+ * Minimum age to watch the media item.
969
+ *
970
+ * @defaultValue `0` (no minimum age)
971
+ */
972
+ minimumAge?: number;
973
+ /**
974
+ * Release date of the media item. Unix timestamp in milliseconds.
975
+ */
976
+ releaseDate?: number;
977
+ /**
978
+ * Time when the media item expires. Unix timestamp in milliseconds.
979
+ */
980
+ endDate?: number;
981
+ /**
982
+ * Whether the media item has product placements.
983
+ */
984
+ hasProductPlacement?: boolean;
985
+ /**
986
+ * Channel of the media item.
987
+ */
988
+ channel?: Channel;
989
+ /**
990
+ * Markers of the media item.
991
+ *
992
+ * @defaultValue `[{ name: KnownMarkerName.PREROLL, type: MarkerType.TIME_IN_SECONDS, threshold: 0 }]`
993
+ */
994
+ markers?: (Marker | CustomMarker)[];
995
+ /**
996
+ * In which country can this media item be played (e.g. `['de', 'at']`)?
997
+ *
998
+ * @defaultValue `['all']` (worldwide)
999
+ */
1000
+ regionsAllowed?: string[];
1001
+ }
1002
+
1003
+ export declare interface Page {
1004
+ url: string;
1005
+ searchParams: Record<string, string>;
1006
+ apexDomain: string;
1007
+ hostname: string;
1008
+ referrer: string;
1009
+ }
1010
+
1011
+ export declare enum PresentationMode {
1012
+ HIDDEN = "hidden",
1013
+ INLINE = "inline",
1014
+ DOCK = "dock",
1015
+ LIGHTBOX = "lightbox",
1016
+ FULLSCREEN = "fullscreen",
1017
+ AMP_DOCK = "amp-dock"
1018
+ }
1019
+
1020
+ declare type PresentationModeString = `${PresentationMode}`;
1021
+
1022
+ export declare enum ScriptType {
1023
+ INTEGRATION_CONFIGS = "application/glomex-integration-configs+json",
1024
+ EXTERNAL_MEDIA_ITEM = "application/glomex-external-media-item+json"
1025
+ }
1026
+
1027
+ export declare enum StreamType {
1028
+ LIVE = "live",
1029
+ VOD = "vod",
1030
+ LIVE_DRM = "live-drm",
1031
+ VOD_DRM = "vod-drm",
1032
+ DYNAMIC_CONTENT = "dynamic-content"
1033
+ }
1034
+
1035
+ export { }
1036
+
1037
+ declare global {
1038
+ interface HTMLElementTagNameMap {
1039
+ [ComponentName.INTEGRATION]: IntegrationElement;
1040
+ [ComponentName.GLOMEX_MEDIA_ITEM]: GlomexMediaItemElement;
1041
+ [ComponentName.EXTERNAL_MEDIA_ITEM]: ExternalMediaItemElement;
1042
+ }
1043
+ interface HTMLElementEventMap extends IntegrationElementEventMap {}
1044
+ }
package/build/index.js ADDED
@@ -0,0 +1 @@
1
+ var e,t,n,o,a,r,i,E,T,d,s,N,l,_,p,c,m,I,A,O;(s=e||(e={})).DEFAULT="turbo-integration",s.SCRIPT="turbo-script",s.IFRAME="turbo-iframe",s.FULLPAGE="turbo-fullpage",s.AMP_VIDEO_IFRAME="turbo-amp-video-iframe",s.AMP_IFRAME="turbo-amp-iframe",(N=t||(t={})).INTEGRATION="glomex-integration",N.EXTERNAL_MEDIA_ITEM="glomex-external-media-item",N.GLOMEX_MEDIA_ITEM="glomex-media-item",(l=n||(n={})).INTEGRATION_CONFIGS="application/glomex-integration-configs+json",l.EXTERNAL_MEDIA_ITEM="application/glomex-external-media-item+json",(_=o||(o={})).HIDDEN="hidden",_.INLINE="inline",_.DOCK="dock",_.LIGHTBOX="lightbox",_.FULLSCREEN="fullscreen",_.AMP_DOCK="amp-dock",(p=a||(a={})).READY="ready",p.INTEGRATION_ABORT="integrationabort",p.INTEGRATION_AD_AVAILABLE="integrationadavailable",p.INTEGRATION_PASSBACK="integrationpassback",p.USER_UPDATE_CONSENT="userupdateconsent",p.PLAYLIST_UPDATE="playlistupdate",p.PLAYER_SET_PRESENTATION_MODE="playersetpresentationmode",p.CONTENT_START="contentstart",p.CONTENT_IMPRESSION="contentimpression",p.CONTENT_STOP="contentstop",p.CONTENT_ERROR="contenterror",p.CONTENT_MARKER_REACHED="contentmarkerreached",p.CONTENT_TIME_UPDATE="timeupdate",p.CONTENT_SEEKING="seeking",p.CONTENT_SEEKED="seeked",p.CONTENT_PLAY="play",p.CONTENT_PAUSE="pause",p.CONTENT_VOLUME_CHANGE="volumechange",p.CONTENT_ENDED="ended",p.AD_IMPRESSION="adimpression",p.AD_TIME_UPDATE="adtimeupdate",p.AD_VOLUME_CHANGE="advolumechange",p.AD_PAUSED="adpaused",p.AD_RESUMED="adresumed",p.AD_CLICK="adclick",p.AD_SKIPPED="adskipped",p.AD_COMPLETE="adcomplete",(c=r||(r={})).TIME_IN_SECONDS="time",c.PERCENT="percent",c.TIME_IN_SECONDS_RECURRING="timeRecurring",(m=i||(i={})).PREROLL="preroll",m.MIDROLL="midroll",m.POSTROLL="postroll",m.FIRST_QUARTILE="contentFirstQuartile",m.MIDPOINT="contentMidpoint",m.THIRD_QUARTILE="contentThirdQuartile",m.COMPLETE="contentComplete",m.STILL_INTERESTING="stillInteresting",(I=E||(E={})).NOT_FOUND="NotFound",I.NOT_AVAILABLE="NotAvailable",I.GEOBLOCKED="Geoblocked",I.YOUTH_PROTECTED="YouthProtected",(A=T||(T={})).HLS="application/vnd.apple.mpegurl",A.HLS_LEGACY="application/x-mpegURL",A.DASH="application/dash+xml",A.MP4="video/mp4",A.OGG="video/ogg",A.WEBM="video/webm",A.MP3="audio/mp3",A.AAC="audio/aac",A.WAV="audio/wav",A.OGG_AUDIO="audio/ogg",A.MPEG_AUDIO="audio/mpeg",A.DYNAMIC_CONTENT="application/x-turbo-dynamic-content",(O=d||(d={})).LIVE="live",O.VOD="vod",O.LIVE_DRM="live-drm",O.VOD_DRM="vod-drm",O.DYNAMIC_CONTENT="dynamic-content";let D="player.glomex.com",u=`https://${D}/integration/1/integration.js`;function C(e){return`https://${D}/variant/${e}/variant.css`}function M(){let e=document.querySelector(`script[src="${u}"]`);return e?Promise.resolve(e):new Promise((e,t)=>{let n=document.createElement("script");n.type="module",n.src=u,n.onload=()=>e(n),n.onerror=()=>t(Error(`Failed to load script ${u}`)),(document.head||document.body).appendChild(n)})}function R(e){if(document.querySelector(`link[href="${C(e)}"]`))return;let t=document.createElement("link");t.rel="stylesheet",t.href=C(e),(document.head||document.body).appendChild(t)}export{t as ComponentName,a as IntegrationEvent,i as KnownMarkerName,r as MarkerType,E as MediaItemErrorCode,T as Mimetype,o as PresentationMode,n as ScriptType,d as StreamType,C as getIntegrationCssUrl,M as loadIntegrationComponent,R as loadIntegrationStyles};
package/package.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "@glomex/integration-web-component",
3
+ "version": "1.1297.1",
4
+ "description": "Web component and types to integrate the glomex player",
5
+ "type": "module",
6
+ "main": "./build/index.js",
7
+ "types": "./build/index.d.ts",
8
+ "files": [
9
+ "build/**/*.js",
10
+ "build/**/*.d.ts"
11
+ ],
12
+ "scripts": {
13
+ "prepare": "npm run build",
14
+ "build": "rm -rf build && tsc --build && rslib build",
15
+ "lint": "tsc --build && biome ci",
16
+ "watch": "tsc --build && rslib build --watch"
17
+ },
18
+ "devDependencies": {
19
+ "@biomejs/biome": "^1.9.4",
20
+ "@glomex/integration": "^1.1297.0",
21
+ "@rslib/core": "^0.5.4",
22
+ "typescript": "^5.8.2"
23
+ },
24
+ "publishConfig": {
25
+ "access": "public"
26
+ },
27
+ "gitHead": "1c5a80d615a212f04f3a5f14b7adf2e9af2ada29"
28
+ }