@streamlayer/feature-advertisement 1.2.0 → 1.2.1-rc.12.pc6c8e1c0

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.
Files changed (96) hide show
  1. package/classic/package.json +5 -0
  2. package/lib/advertisement.d.ts +6 -6
  3. package/lib/advertisement.js +9 -9
  4. package/lib/cjs/advertisement.d.ts +64 -0
  5. package/lib/cjs/advertisement.js +322 -0
  6. package/lib/cjs/index.d.ts +21 -0
  7. package/lib/cjs/index.js +41 -0
  8. package/lib/cjs/package.json +1 -0
  9. package/lib/cjs/units/ad-macros.d.ts +7 -0
  10. package/lib/cjs/units/ad-macros.js +91 -0
  11. package/lib/cjs/units/external-ad.d.ts +127 -0
  12. package/lib/cjs/units/external-ad.js +421 -0
  13. package/lib/cjs/units/external-pause-ad.d.ts +50 -0
  14. package/lib/cjs/units/external-pause-ad.js +259 -0
  15. package/lib/cjs/units/gam.d.ts +26 -0
  16. package/lib/cjs/units/gam.js +152 -0
  17. package/lib/cjs/units/parse-vast-extensions.d.ts +26 -0
  18. package/lib/cjs/units/parse-vast-extensions.js +56 -0
  19. package/lib/cjs/units/pause-ad-card.d.ts +49 -0
  20. package/lib/cjs/units/pause-ad-card.js +136 -0
  21. package/lib/cjs/units/pause-ad.d.ts +16 -0
  22. package/lib/cjs/units/pause-ad.js +52 -0
  23. package/lib/cjs/units/sponsor-logo.d.ts +78 -0
  24. package/lib/cjs/units/sponsor-logo.js +194 -0
  25. package/lib/cjs/units/ssai-ad-break.d.ts +21 -0
  26. package/lib/cjs/units/ssai-ad-break.js +11 -0
  27. package/lib/cjs/units/ssai-creative.d.ts +89 -0
  28. package/lib/cjs/units/ssai-creative.js +136 -0
  29. package/lib/cjs/units/ssai-detector.d.ts +180 -0
  30. package/lib/cjs/units/ssai-detector.js +1172 -0
  31. package/lib/cjs/units/ssai-log.d.ts +16 -0
  32. package/lib/cjs/units/ssai-log.js +23 -0
  33. package/lib/cjs/units/ssai-preload.d.ts +20 -0
  34. package/lib/cjs/units/ssai-preload.js +62 -0
  35. package/lib/cjs/units/ssai-providers.d.ts +117 -0
  36. package/lib/cjs/units/ssai-providers.js +300 -0
  37. package/lib/cjs/units/vast-tracker.d.ts +45 -0
  38. package/lib/cjs/units/vast-tracker.js +64 -0
  39. package/lib/classic/_virtual/_rollupPluginBabelHelpers.js +71 -0
  40. package/lib/classic/advertisement.js +348 -0
  41. package/lib/classic/cjs/_virtual/_rollupPluginBabelHelpers.js +77 -0
  42. package/lib/classic/cjs/advertisement.js +350 -0
  43. package/lib/classic/cjs/index.js +49 -0
  44. package/lib/classic/cjs/package.json +1 -0
  45. package/lib/classic/cjs/units/ad-macros.js +115 -0
  46. package/lib/classic/cjs/units/external-ad.js +500 -0
  47. package/lib/classic/cjs/units/external-pause-ad.js +278 -0
  48. package/lib/classic/cjs/units/gam.js +173 -0
  49. package/lib/classic/cjs/units/parse-vast-extensions.js +60 -0
  50. package/lib/classic/cjs/units/pause-ad-card.js +134 -0
  51. package/lib/classic/cjs/units/pause-ad.js +72 -0
  52. package/lib/classic/cjs/units/sponsor-logo.js +201 -0
  53. package/lib/classic/cjs/units/ssai-ad-break.js +11 -0
  54. package/lib/classic/cjs/units/ssai-creative.js +142 -0
  55. package/lib/classic/cjs/units/ssai-detector.js +1195 -0
  56. package/lib/classic/cjs/units/ssai-log.js +23 -0
  57. package/lib/classic/cjs/units/ssai-preload.js +72 -0
  58. package/lib/classic/cjs/units/ssai-providers.js +361 -0
  59. package/lib/classic/cjs/units/vast-tracker.js +81 -0
  60. package/lib/classic/index.js +29 -0
  61. package/lib/classic/units/ad-macros.js +113 -0
  62. package/lib/classic/units/external-ad.js +491 -0
  63. package/lib/classic/units/external-pause-ad.js +275 -0
  64. package/lib/classic/units/gam.js +171 -0
  65. package/lib/classic/units/parse-vast-extensions.js +58 -0
  66. package/lib/classic/units/pause-ad-card.js +131 -0
  67. package/lib/classic/units/pause-ad.js +70 -0
  68. package/lib/classic/units/sponsor-logo.js +197 -0
  69. package/lib/classic/units/ssai-ad-break.js +9 -0
  70. package/lib/classic/units/ssai-creative.js +140 -0
  71. package/lib/classic/units/ssai-detector.js +1192 -0
  72. package/lib/classic/units/ssai-log.js +21 -0
  73. package/lib/classic/units/ssai-preload.js +68 -0
  74. package/lib/classic/units/ssai-providers.js +351 -0
  75. package/lib/classic/units/vast-tracker.js +77 -0
  76. package/lib/index.d.ts +15 -14
  77. package/lib/index.js +9 -9
  78. package/lib/units/external-ad.d.ts +2 -2
  79. package/lib/units/external-ad.js +3 -3
  80. package/lib/units/external-pause-ad.js +1 -1
  81. package/lib/units/gam.js +1 -1
  82. package/lib/units/pause-ad.d.ts +1 -1
  83. package/lib/units/pause-ad.js +1 -1
  84. package/lib/units/sponsor-logo.d.ts +12 -4
  85. package/lib/units/sponsor-logo.js +4 -3
  86. package/lib/units/ssai-ad-break.d.ts +1 -1
  87. package/lib/units/ssai-creative.d.ts +1 -1
  88. package/lib/units/ssai-creative.js +1 -1
  89. package/lib/units/ssai-detector.d.ts +1 -1
  90. package/lib/units/ssai-detector.js +1 -1
  91. package/lib/units/ssai-preload.d.ts +1 -1
  92. package/lib/units/ssai-providers.d.ts +1 -1
  93. package/lib/units/ssai-providers.js +1 -1
  94. package/lib/units/vast-tracker.d.ts +1 -1
  95. package/lib/vast-client.d.ts +9 -0
  96. package/package.json +42 -9
@@ -0,0 +1,72 @@
1
+ 'use strict';
2
+
3
+ var _rollupPluginBabelHelpers = require('../_virtual/_rollupPluginBabelHelpers.js');
4
+ var classic = require('@streamlayer/sdk-web-logger/classic');
5
+ var nanostores = require('nanostores');
6
+ require('@streamlayer/sdk-web-api/classic');
7
+ require('@streamlayer/sdk-web-core/classic/store');
8
+ var interactive_feed_pb = require('@streamlayer/sl-eslib/interactive/feed/interactive.feed_pb');
9
+ var pauseAdCard = require('./pause-ad-card.js');
10
+
11
+ const log = classic.createLogger('advertisement:pause-ad');
12
+ const pauseAdListStore = instance => {
13
+ const $slStreamId = instance.stores.slStreamId.getAtomStore();
14
+ return ($enabled, options) => {
15
+ const {
16
+ client,
17
+ queryKey
18
+ } = instance.transport.createPromiseClient(interactive_feed_pb.Feed, {
19
+ method: 'pauseAdList',
20
+ params: [$slStreamId, $enabled]
21
+ });
22
+ const $list = instance.transport.nanoquery.createFetcherStore(queryKey, {
23
+ dedupeTime: 0,
24
+ revalidateInterval: options.refetchInterval > 0 ? options.refetchInterval : 0,
25
+ fetcher: function () {
26
+ var _ref = _rollupPluginBabelHelpers.asyncToGenerator(function* (_, __, eventId, isEnabled) {
27
+ var _res$data;
28
+ if (!eventId || typeof eventId !== 'string' || !isEnabled) {
29
+ return [];
30
+ }
31
+ log.debug({
32
+ eventId
33
+ }, 'fetching pause ad list');
34
+ const res = yield client.pauseAdList({
35
+ eventId
36
+ });
37
+ const cards = pauseAdCard.parsePauseAdCards((_res$data = res.data) !== null && _res$data !== void 0 ? _res$data : []);
38
+ log.debug({
39
+ count: cards.length
40
+ }, 'parsed %d fullbleed pause ad cards');
41
+ return cards;
42
+ });
43
+ return function fetcher(_x, _x2, _x3, _x4) {
44
+ return _ref.apply(this, arguments);
45
+ };
46
+ }()
47
+ });
48
+ const $index = nanostores.atom(0);
49
+ const next = () => {
50
+ const list = $list.get().data;
51
+ if (!(list !== null && list !== void 0 && list.length)) return;
52
+ $index.set(($index.get() + 1) % list.length);
53
+ };
54
+ const reset = () => {
55
+ $index.set(0);
56
+ };
57
+ const getCurrent = () => {
58
+ const list = $list.get().data;
59
+ if (!(list !== null && list !== void 0 && list.length)) return undefined;
60
+ return list[$index.get()];
61
+ };
62
+ return {
63
+ $list,
64
+ $index,
65
+ next,
66
+ reset,
67
+ getCurrent
68
+ };
69
+ };
70
+ };
71
+
72
+ exports.pauseAdListStore = pauseAdListStore;
@@ -0,0 +1,201 @@
1
+ 'use strict';
2
+
3
+ require('core-js/modules/es.array.push.js');
4
+ require('core-js/modules/esnext.iterator.constructor.js');
5
+ require('core-js/modules/esnext.iterator.filter.js');
6
+ require('core-js/modules/esnext.iterator.map.js');
7
+
8
+ /**
9
+ * Sponsor-logo slot selection for a **feature** ad unit (Insight, Prediction and Trivia today;
10
+ * Poll is the same shape and is a separate ticket).
11
+ *
12
+ * Deliberately NOT `selectCompanions` (`./external-ad.ts`). That rule is the *display*-unit rule:
13
+ * it promotes a companion to the logo slot only when the tag ships an exact 300x75 `<Companion>`
14
+ * next to at least one other. A feature ad-unit tag is typically a **single** creative — often a
15
+ * lone NonLinear `<StaticResource>` — where the ad IS the logo, which is exactly the shape that
16
+ * rule returns nothing for. `selectCompanions` stays untouched: SC-335's three shipped units
17
+ * depend on its exact behaviour and impression counts are billing-visible.
18
+ *
19
+ * Mirrors iOS `SLRVASTSlotRole.logo` + `SLRVASTAssetPool`
20
+ * (`StreamLayerSDK/Frameworks/SLRGAMFramework/Sources/VASTSlotFiller/`):
21
+ *
22
+ * - **Images only.** A video-only tag yields no logo. `<Icon>` is never projected — icons hang off
23
+ * the `<Linear>` creative, which this selector does not look at. A `<StaticResource>` the tag
24
+ * declares as a non-image `creativeType` is skipped too, so a companion that lists a script
25
+ * before its image still resolves to the image (see `isImageResource`).
26
+ * - **Origin-agnostic.** A lone NonLinear `<StaticResource>` is as valid as a `<Companion>`.
27
+ * - **Aspect-dominant** toward 1:1: the smallest `|log(assetAspect) - log(1)|` wins, ties broken by
28
+ * larger area, then by higher pixel density. Aspect is a *preference, never a filter* — the only
29
+ * hard constraint is the asset kind, so a badly shaped asset still wins if it is the only one.
30
+ * - Assets whose intrinsic size the tag never declared rank last, but still beat nothing.
31
+ *
32
+ * The module also hosts iOS's second logo role, `SLRVASTSlotRole.cardLogo` (`selectCardLogo`) —
33
+ * the same ranking narrowed to `<Companion>` origins, for the hero-card display units.
34
+ */
35
+ // eslint-disable-next-line @typescript-eslint/triple-slash-reference
36
+ /// <reference path="../module.d.ts" />
37
+ /** `width`/`height` are XML attributes (strings at runtime); 0 and NaN both mean "not declared". */
38
+ const toSize = value => {
39
+ const size = Number(value);
40
+ return size > 0 ? size : undefined;
41
+ };
42
+ /**
43
+ * VAST 4 `<CompanionAds pxratio>`; `@dailymotion/vast-client` defaults it to `'1'` and the
44
+ * `@types/vast-client` shim does not declare it, hence the loose read.
45
+ */
46
+ const toPxRatio = variation => {
47
+ return Number(variation.pxratio) || 1;
48
+ };
49
+ /**
50
+ * `<StaticResource creativeType>`. The slot draws an `<img>`, so a resource the tag declares as
51
+ * anything else — the `application/x-shockwave-flash` or `application/javascript` creative a
52
+ * companion may list beside its image — must never fill it: it would swap the proto logo for a
53
+ * broken image AND still fire an impression for something nobody ever saw.
54
+ *
55
+ * An ABSENT type is not a rejection. VAST requires the attribute but real GAM image companions
56
+ * routinely omit it, and this module's only hard constraint is the asset kind, so an undeclared
57
+ * type stays a candidate. `@dailymotion/vast-client` writes `0` for a missing NonLinear
58
+ * `creativeType` and `null` for a missing companion one; both are falsy, hence the single guard.
59
+ */
60
+ const isImageResource = creativeType => {
61
+ if (!creativeType) {
62
+ return true;
63
+ }
64
+ return String(creativeType).toLowerCase().indexOf('image/') === 0;
65
+ };
66
+ /**
67
+ * The first resource a `<Companion>` declares as an image (or leaves undeclared). NOT
68
+ * `staticResources[0]`: the order in the tag is the advertiser's, and a non-image resource listed
69
+ * first must not hide a usable image behind it.
70
+ */
71
+ const pickCompanionImage = variation => {
72
+ const resources = variation.staticResources || [];
73
+ for (let i = 0; i < resources.length; i++) {
74
+ const resource = resources[i];
75
+ if (resource && resource.url && isImageResource(resource.creativeType)) {
76
+ return resource.url;
77
+ }
78
+ }
79
+ return undefined;
80
+ };
81
+ /** Distance from square on a log scale, so 2:1 and 1:2 are equally far from 1:1. */
82
+ const aspectDistance = asset => {
83
+ if (!asset.width || !asset.height) {
84
+ // Unknown intrinsic size — rank last, but still a candidate.
85
+ return Infinity;
86
+ }
87
+ return Math.abs(Math.log(asset.width / asset.height));
88
+ };
89
+ const collectAssetsFrom = ad => {
90
+ const assets = [];
91
+ for (let i = 0; i < ad.creatives.length; i++) {
92
+ const creative = ad.creatives[i];
93
+ if (creative.type === 'companion') {
94
+ const companionCreative = creative;
95
+ const variations = companionCreative.variations || [];
96
+ for (let j = 0; j < variations.length; j++) {
97
+ const variation = variations[j];
98
+ const imageUrl = variation && pickCompanionImage(variation);
99
+ if (imageUrl) {
100
+ var _variation$companionC;
101
+ assets.push({
102
+ imageUrl,
103
+ clickUrl: (_variation$companionC = variation.companionClickThroughURLTemplate) !== null && _variation$companionC !== void 0 ? _variation$companionC : undefined,
104
+ width: toSize(variation.width),
105
+ height: toSize(variation.height),
106
+ origin: 'companion',
107
+ creative: companionCreative,
108
+ variation
109
+ });
110
+ }
111
+ }
112
+ continue;
113
+ }
114
+ if (creative.type === 'nonlinear') {
115
+ const nonLinearCreative = creative;
116
+ const variations = nonLinearCreative.variations || [];
117
+ for (let j = 0; j < variations.length; j++) {
118
+ const variation = variations[j];
119
+ // `type` is where the parser puts a `<NonLinear>`'s `creativeType`, and it is written last
120
+ // from the `<StaticResource>` element, so it describes `staticResource` whenever that is
121
+ // set. An HTML- or iframe-typed variation carries no `staticResource` and drops out here.
122
+ const imageUrl = variation && isImageResource(variation.type) ? variation.staticResource : undefined;
123
+ if (imageUrl) {
124
+ var _variation$nonlinearC;
125
+ assets.push({
126
+ imageUrl,
127
+ // 6.4.2 emits `nonlinearClickThroughURLTemplate` (lower-case `l`); the shim declares
128
+ // the upper-case spelling. The runtime one is authoritative — see `getNonLinear`.
129
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
130
+ // @ts-ignore
131
+ clickUrl: (_variation$nonlinearC = variation.nonlinearClickThroughURLTemplate) !== null && _variation$nonlinearC !== void 0 ? _variation$nonlinearC : undefined,
132
+ width: toSize(variation.width),
133
+ height: toSize(variation.height),
134
+ origin: 'nonlinear',
135
+ creative: nonLinearCreative,
136
+ variation
137
+ });
138
+ }
139
+ }
140
+ }
141
+ }
142
+ return assets;
143
+ };
144
+ /**
145
+ * The shared ranking both roles use: aspect distance from 1:1, ties broken by larger area, then by
146
+ * higher pixel density. Aspect is a preference, never a filter — the best of a bad set still wins.
147
+ */
148
+ const rankBest = assets => {
149
+ if (!assets.length) {
150
+ return undefined;
151
+ }
152
+ let best = assets[0];
153
+ let bestDistance = aspectDistance(best);
154
+ let bestArea = (best.width || 0) * (best.height || 0);
155
+ let bestPxRatio = toPxRatio(best.variation);
156
+ for (let i = 1; i < assets.length; i++) {
157
+ const asset = assets[i];
158
+ const distance = aspectDistance(asset);
159
+ const area = (asset.width || 0) * (asset.height || 0);
160
+ const pxRatio = toPxRatio(asset.variation);
161
+ const wins = distance !== bestDistance ? distance < bestDistance : area !== bestArea ? area > bestArea : pxRatio > bestPxRatio;
162
+ if (wins) {
163
+ best = asset;
164
+ bestDistance = distance;
165
+ bestArea = area;
166
+ bestPxRatio = pxRatio;
167
+ }
168
+ }
169
+ return best;
170
+ };
171
+ /**
172
+ * Pick the image a parsed VAST ad offers for a sponsor-logo slot, or `undefined` when it offers
173
+ * none (a video-only tag, or an empty response). A caller that gets `undefined` must fall back to
174
+ * its own proto/Studio logo rather than suppressing the card.
175
+ */
176
+ const collectAssets = ad => collectAssetsFrom(ad);
177
+ const selectSponsorLogo = ad => rankBest(collectAssetsFrom(ad));
178
+ /**
179
+ * iOS `SLRVASTSlotRole.cardLogo` — the sponsor logo of a **hero card** (1:1 / 2:1 / Picture in
180
+ * Picture / Side-by-Side / Sponsor Frame). Same 1:1 aspect-dominant ranking as `.logo`, plus the
181
+ * one constraint that distinguishes the two roles:
182
+ *
183
+ * - **`requiredOrigin: .companion`.** A NonLinear image is a hero creative, never a logo. iOS's
184
+ * reason: a leftover hero-type asset — a second `<NonLinear>` overlay, or a stray image still in
185
+ * the pool after the hero role claimed its own — must never leak into the card's logo slot,
186
+ * where it would render at logo size as an unreadable smudge of the advertiser's key art.
187
+ * `nonlinear_full` is the fixture that pins it: `.logo` takes the 500x500 NonLinear, `.cardLogo`
188
+ * must take the 200x200 `<Companion>`.
189
+ * - **`exclude`** mirrors iOS's **greedy** `pool.select([hero, .cardLogo])`: roles resolve in array
190
+ * order and an asset a role claims is removed from the pool for every later role. We have no
191
+ * pool object, so the caller passes the assets the hero already claimed and they are filtered
192
+ * out here by `imageUrl`.
193
+ */
194
+ const selectCardLogo = (ad, exclude) => {
195
+ const claimed = (exclude || []).map(item => item === null || item === void 0 ? void 0 : item.imageUrl).filter(url => !!url);
196
+ return rankBest(collectAssetsFrom(ad).filter(asset => asset.origin === 'companion' && claimed.indexOf(asset.imageUrl) === -1));
197
+ };
198
+
199
+ exports.collectAssets = collectAssets;
200
+ exports.selectCardLogo = selectCardLogo;
201
+ exports.selectSponsorLogo = selectSponsorLogo;
@@ -0,0 +1,11 @@
1
+ 'use strict';
2
+
3
+ var classic = require('@streamlayer/sdk-web-interfaces/classic');
4
+
5
+ /**
6
+ * Imperative atom driven directly by the detector (no nanoquery — the trigger
7
+ * is push-based, not request/response).
8
+ */
9
+ const createSsaiAdBreakStore = () => classic.createSingleStore(null);
10
+
11
+ exports.createSsaiAdBreakStore = createSsaiAdBreakStore;
@@ -0,0 +1,142 @@
1
+ 'use strict';
2
+
3
+ var _rollupPluginBabelHelpers = require('../_virtual/_rollupPluginBabelHelpers.js');
4
+ require('core-js/modules/es.array.iterator.js');
5
+ require('core-js/modules/es.promise.js');
6
+ require('core-js/modules/esnext.iterator.constructor.js');
7
+ require('core-js/modules/esnext.iterator.for-each.js');
8
+ require('core-js/modules/web.dom-collections.for-each.js');
9
+ require('core-js/modules/web.dom-collections.iterator.js');
10
+ var ssaiProviders = require('./ssai-providers.js');
11
+
12
+ /**
13
+ * Per-instance cache + impression-firing wrapper around a SsaiCreativeProvider.
14
+ * Caches resolved creatives by creativeId so repeated active-ad polls and pod
15
+ * repeats don't refetch. In-flight fetches are cancellable via AbortController.
16
+ */
17
+ class SsaiCreativeCache {
18
+ constructor(provider) {
19
+ _rollupPluginBabelHelpers.defineProperty(this, "provider", void 0);
20
+ _rollupPluginBabelHelpers.defineProperty(this, "cache", new Map());
21
+ _rollupPluginBabelHelpers.defineProperty(this, "inflight", new Map());
22
+ /**
23
+ * The already-resolved creative, or undefined — synchronous on purpose: a
24
+ * prefetched creative lets the ad break flip straight to 'ready' with no
25
+ * async gap (which the UI would render as a blink between two ads of a pod).
26
+ */
27
+ _rollupPluginBabelHelpers.defineProperty(this, "peek", creativeId => this.cache.get(creativeId));
28
+ _rollupPluginBabelHelpers.defineProperty(this, "resolve", creativeId => {
29
+ const cached = this.cache.get(creativeId);
30
+ if (cached) {
31
+ return Promise.resolve(cached);
32
+ }
33
+ const existing = this.inflight.get(creativeId);
34
+ if (existing) {
35
+ return existing.promise;
36
+ }
37
+ const controller = new AbortController();
38
+ const promise = this.provider.resolve(creativeId, controller.signal).then(creative => {
39
+ this.cache.set(creativeId, creative);
40
+ this.inflight.delete(creativeId);
41
+ return creative;
42
+ }).catch(error => {
43
+ this.inflight.delete(creativeId);
44
+ throw error;
45
+ });
46
+ this.inflight.set(creativeId, {
47
+ promise,
48
+ controller
49
+ });
50
+ return promise;
51
+ });
52
+ /**
53
+ * Cancel an in-flight fetch (e.g. the break ended before it resolved).
54
+ */
55
+ _rollupPluginBabelHelpers.defineProperty(this, "cancel", creativeId => {
56
+ const existing = this.inflight.get(creativeId);
57
+ if (existing) {
58
+ existing.controller.abort();
59
+ this.inflight.delete(creativeId);
60
+ }
61
+ });
62
+ /**
63
+ * Fire the impression for a creative. Delegates to the provider's
64
+ * `fireImpression` when present, otherwise the shared default (first
65
+ * trackingEvent named 'impression' via sendBeacon/fetch). Called once per
66
+ * visible appearance of the bar (the UI dedupes the ~250ms active-poll so a
67
+ * single continuous appearance fires exactly one impression). Each genuine pod
68
+ * insertion of the same creative is a distinct impression and re-fires.
69
+ */
70
+ _rollupPluginBabelHelpers.defineProperty(this, "fireImpression", creative => {
71
+ if (this.provider.fireImpression) {
72
+ this.provider.fireImpression(creative);
73
+ return;
74
+ }
75
+ ssaiProviders.fireDefaultImpression(creative);
76
+ });
77
+ /**
78
+ * Fire the impression for an already-resolved creativeId. No-op if the
79
+ * creative isn't cached yet (the bar only renders once resolved, so by the
80
+ * time the UI calls this the creative is present).
81
+ */
82
+ _rollupPluginBabelHelpers.defineProperty(this, "fireImpressionById", creativeId => {
83
+ const creative = this.cache.get(creativeId);
84
+ if (creative) {
85
+ this.fireImpression(creative);
86
+ }
87
+ });
88
+ /**
89
+ * Fire a lifecycle / click beacon. Delegates to the provider's `fireTracking`
90
+ * when it defines one, otherwise fires every matching `trackingEvents` URL.
91
+ */
92
+ _rollupPluginBabelHelpers.defineProperty(this, "fireTracking", (creative, event) => {
93
+ if (this.provider.fireTracking) {
94
+ this.provider.fireTracking(creative, event);
95
+ return;
96
+ }
97
+ ssaiProviders.fireTrackingEvents(creative, event);
98
+ });
99
+ /**
100
+ * Fire a beacon for a creativeId that may still be resolving.
101
+ *
102
+ * `start` in particular lands the instant the break opens, which is usually
103
+ * BEFORE the metadata request has come back — dropping it would silently lose
104
+ * the first beacon of every ad. Resolution is already in flight by then and
105
+ * `resolve` returns that same promise, so this attaches to it rather than
106
+ * issuing a second request. A creative that never resolves fires nothing,
107
+ * which is the correct outcome: there are no URLs to fire.
108
+ */
109
+ _rollupPluginBabelHelpers.defineProperty(this, "fireTrackingById", (creativeId, event) => {
110
+ const cached = this.cache.get(creativeId);
111
+ if (cached) {
112
+ this.fireTracking(cached, event);
113
+ return;
114
+ }
115
+ this.resolve(creativeId).then(creative => this.fireTracking(creative, event)).catch(() => undefined);
116
+ });
117
+ /**
118
+ * Fire the companion's `clickTracking` beacons. Separate from
119
+ * {@link fireTracking} because these live on the companion, not in
120
+ * `trackingEvents` — a provider's `fireTracking` override has no say over them.
121
+ */
122
+ _rollupPluginBabelHelpers.defineProperty(this, "fireCompanionClickById", creativeId => {
123
+ var _this$cache$get;
124
+ const companion = (_this$cache$get = this.cache.get(creativeId)) === null || _this$cache$get === void 0 ? void 0 : _this$cache$get.companion;
125
+ if (!companion) {
126
+ return;
127
+ }
128
+ for (const url of companion.clickTracking) {
129
+ ssaiProviders.fireBeacon(url);
130
+ }
131
+ });
132
+ _rollupPluginBabelHelpers.defineProperty(this, "destroy", () => {
133
+ this.inflight.forEach(entry => entry.controller.abort());
134
+ this.inflight.clear();
135
+ this.cache.clear();
136
+ });
137
+ this.provider = provider;
138
+ }
139
+ }
140
+
141
+ exports.DEFAULT_CREATIVE_API_BASE = ssaiProviders.DEFAULT_CREATIVE_API_BASE;
142
+ exports.SsaiCreativeCache = SsaiCreativeCache;