prebid.js 9.0.0 → 9.2.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.
Files changed (307) hide show
  1. package/.nvmrc +1 -1
  2. package/browsers.json +3 -3
  3. package/dist/33acrossAnalyticsAdapter.js +1 -1
  4. package/dist/33acrossBidAdapter.js +1 -1
  5. package/dist/33acrossIdSystem.js +1 -1
  6. package/dist/BTBidAdapter.js +1 -1
  7. package/dist/acuityadsBidAdapter.js +1 -1
  8. package/dist/adagioAnalyticsAdapter.js +1 -1
  9. package/dist/adagioBidAdapter.js +1 -1
  10. package/dist/adagioRtdProvider.js +1 -1
  11. package/dist/adagioUtils.js +1 -0
  12. package/dist/adgenerationBidAdapter.js +1 -1
  13. package/dist/admanBidAdapter.js +1 -1
  14. package/dist/adpod.js +1 -1
  15. package/dist/adprimeBidAdapter.js +1 -1
  16. package/dist/adqueryBidAdapter.js +1 -1
  17. package/dist/adrelevantisBidAdapter.js +1 -1
  18. package/dist/adstirBidAdapter.js +1 -1
  19. package/dist/adtrgtmeBidAdapter.js +1 -1
  20. package/dist/adxcgBidAdapter.js +1 -1
  21. package/dist/adyoulikeBidAdapter.js +1 -1
  22. package/dist/agmaAnalyticsAdapter.js +1 -1
  23. package/dist/ajaBidAdapter.js +1 -1
  24. package/dist/amxBidAdapter.js +1 -1
  25. package/dist/amxIdSystem.js +1 -1
  26. package/dist/appierAnalyticsAdapter.js +1 -1
  27. package/dist/appnexusBidAdapter.js +1 -1
  28. package/dist/appnexusUtils.js +1 -1
  29. package/dist/asoBidAdapter.js +1 -1
  30. package/dist/autoplayDetection.js +1 -1
  31. package/dist/axisBidAdapter.js +1 -1
  32. package/dist/axonixBidAdapter.js +1 -1
  33. package/dist/beyondmediaBidAdapter.js +1 -1
  34. package/dist/bidglassBidAdapter.js +1 -1
  35. package/dist/big-richmediaBidAdapter.js +1 -1
  36. package/dist/bliinkBidAdapter.js +1 -1
  37. package/dist/boldwinBidAdapter.js +1 -1
  38. package/dist/bridBidAdapter.js +1 -1
  39. package/dist/bridgewellBidAdapter.js +1 -1
  40. package/dist/brightMountainMediaBidAdapter.js +1 -1
  41. package/dist/carodaBidAdapter.js +1 -1
  42. package/dist/chtnwBidAdapter.js +1 -1
  43. package/dist/chunk-core.js +1 -1
  44. package/dist/compassBidAdapter.js +1 -1
  45. package/dist/concertBidAdapter.js +1 -1
  46. package/dist/connectadBidAdapter.js +1 -1
  47. package/dist/consumableBidAdapter.js +1 -1
  48. package/dist/contentexchangeBidAdapter.js +1 -1
  49. package/dist/conversantAnalyticsAdapter.js +1 -1
  50. package/dist/conversantBidAdapter.js +1 -1
  51. package/dist/craftBidAdapter.js +1 -1
  52. package/dist/criteoBidAdapter.js +1 -1
  53. package/dist/cwireBidAdapter.js +1 -1
  54. package/dist/dailymotionBidAdapter.js +1 -1
  55. package/dist/dependencies.json +83 -4
  56. package/dist/dspxBidAdapter.js +1 -1
  57. package/dist/dxkultureBidAdapter.js +1 -1
  58. package/dist/e_volutionBidAdapter.js +1 -1
  59. package/dist/emtvBidAdapter.js +1 -1
  60. package/dist/eplanningBidAdapter.js +1 -1
  61. package/dist/euidIdSystem.js +1 -1
  62. package/dist/exadsBidAdapter.js +1 -1
  63. package/dist/feedadBidAdapter.js +1 -1
  64. package/dist/finativeBidAdapter.js +1 -1
  65. package/dist/freewheel-sspBidAdapter.js +1 -1
  66. package/dist/globalsunBidAdapter.js +1 -1
  67. package/dist/gmosspBidAdapter.js +1 -1
  68. package/dist/goldbachBidAdapter.js +1 -1
  69. package/dist/greenbidsAnalyticsAdapter.js +1 -1
  70. package/dist/greenbidsRtdProvider.js +1 -1
  71. package/dist/gridBidAdapter.js +1 -1
  72. package/dist/gumgumBidAdapter.js +1 -1
  73. package/dist/h12mediaBidAdapter.js +1 -1
  74. package/dist/hypelabBidAdapter.js +1 -1
  75. package/dist/id5IdSystem.js +1 -1
  76. package/dist/illuminBidAdapter.js +1 -1
  77. package/dist/imdsBidAdapter.js +1 -1
  78. package/dist/improvedigitalBidAdapter.js +1 -1
  79. package/dist/insticatorBidAdapter.js +1 -1
  80. package/dist/iqzoneBidAdapter.js +1 -1
  81. package/dist/ixBidAdapter.js +1 -1
  82. package/dist/jixieBidAdapter.js +1 -1
  83. package/dist/justpremiumBidAdapter.js +1 -1
  84. package/dist/kargoBidAdapter.js +1 -1
  85. package/dist/kimberliteBidAdapter.js +1 -1
  86. package/dist/kiviadsBidAdapter.js +1 -1
  87. package/dist/konduitAnalyticsAdapter.js +1 -1
  88. package/dist/krushmediaBidAdapter.js +1 -1
  89. package/dist/kueezBidAdapter.js +1 -1
  90. package/dist/kueezRtbBidAdapter.js +1 -1
  91. package/dist/lassoBidAdapter.js +1 -1
  92. package/dist/lifestreetBidAdapter.js +1 -1
  93. package/dist/liveIntentIdSystem.js +1 -1
  94. package/dist/logicadBidAdapter.js +1 -1
  95. package/dist/loglyliftBidAdapter.js +1 -1
  96. package/dist/loyalBidAdapter.js +1 -1
  97. package/dist/luceadBidAdapter.js +1 -1
  98. package/dist/lunamediahbBidAdapter.js +1 -1
  99. package/dist/magniteAnalyticsAdapter.js +1 -1
  100. package/dist/malltvAnalyticsAdapter.js +1 -1
  101. package/dist/marsmediaBidAdapter.js +1 -1
  102. package/dist/mathildeadsBidAdapter.js +1 -1
  103. package/dist/mediafuseBidAdapter.js +1 -1
  104. package/dist/mediasquareBidAdapter.js +1 -1
  105. package/dist/mgidBidAdapter.js +1 -1
  106. package/dist/mgidXBidAdapter.js +1 -1
  107. package/dist/minutemediaBidAdapter.js +1 -1
  108. package/dist/missenaBidAdapter.js +1 -1
  109. package/dist/mobfoxpbBidAdapter.js +1 -1
  110. package/dist/mobianRtdProvider.js +1 -0
  111. package/dist/nexx360BidAdapter.js +1 -1
  112. package/dist/nobidAnalyticsAdapter.js +1 -1
  113. package/dist/nobidBidAdapter.js +1 -1
  114. package/dist/not-for-prod/prebid.js +190 -186
  115. package/dist/oguryBidAdapter.js +1 -1
  116. package/dist/onetagBidAdapter.js +1 -1
  117. package/dist/ooloAnalyticsAdapter.js +1 -1
  118. package/dist/openwebBidAdapter.js +1 -1
  119. package/dist/openxBidAdapter.js +1 -1
  120. package/dist/optidigitalBidAdapter.js +1 -1
  121. package/dist/ortbConverter.js +1 -1
  122. package/dist/outbrainBidAdapter.js +1 -1
  123. package/dist/ozoneBidAdapter.js +1 -1
  124. package/dist/paapi.js +1 -1
  125. package/dist/pgamsspBidAdapter.js +1 -1
  126. package/dist/pixfutureBidAdapter.js +1 -1
  127. package/dist/playdigoBidAdapter.js +1 -1
  128. package/dist/prebidServerBidAdapter.js +1 -1
  129. package/dist/pubCircleBidAdapter.js +1 -1
  130. package/dist/publinkIdSystem.js +1 -1
  131. package/dist/publirBidAdapter.js +1 -1
  132. package/dist/pubmaticAnalyticsAdapter.js +1 -1
  133. package/dist/pubmaticBidAdapter.js +1 -1
  134. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  135. package/dist/pubxaiAnalyticsAdapter.js +1 -1
  136. package/dist/pxyzBidAdapter.js +1 -1
  137. package/dist/qtBidAdapter.js +1 -1
  138. package/dist/quantcastBidAdapter.js +1 -1
  139. package/dist/raynRtdProvider.js +1 -1
  140. package/dist/readpeakBidAdapter.js +1 -1
  141. package/dist/relaidoBidAdapter.js +1 -1
  142. package/dist/retailspotBidAdapter.js +1 -1
  143. package/dist/rhythmoneBidAdapter.js +1 -1
  144. package/dist/richaudienceBidAdapter.js +1 -0
  145. package/dist/ringieraxelspringerBidAdapter.js +1 -1
  146. package/dist/riseBidAdapter.js +1 -1
  147. package/dist/rubiconBidAdapter.js +1 -1
  148. package/dist/seedingAllianceBidAdapter.js +1 -1
  149. package/dist/seedtagBidAdapter.js +1 -1
  150. package/dist/setupadBidAdapter.js +1 -1
  151. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  152. package/dist/sharethroughBidAdapter.js +1 -1
  153. package/dist/shinezBidAdapter.js +1 -1
  154. package/dist/shinezRtbBidAdapter.js +1 -1
  155. package/dist/smaatoBidAdapter.js +1 -1
  156. package/dist/smartadserverBidAdapter.js +1 -1
  157. package/dist/smartxBidAdapter.js +1 -1
  158. package/dist/smartytechBidAdapter.js +1 -1
  159. package/dist/smilewantedBidAdapter.js +1 -1
  160. package/dist/sonobiBidAdapter.js +1 -1
  161. package/dist/sovrnBidAdapter.js +1 -1
  162. package/dist/sspBCBidAdapter.js +1 -1
  163. package/dist/stnBidAdapter.js +1 -1
  164. package/dist/stvBidAdapter.js +1 -1
  165. package/dist/sublimeBidAdapter.js +1 -1
  166. package/dist/taboolaBidAdapter.js +1 -1
  167. package/dist/tagorasBidAdapter.js +1 -1
  168. package/dist/targetVideoBidAdapter.js +1 -1
  169. package/dist/teadsBidAdapter.js +1 -1
  170. package/dist/teqblazeUtils.js +1 -0
  171. package/dist/themoneytizerBidAdapter.js +1 -1
  172. package/dist/topicsFpdModule.js +1 -1
  173. package/dist/trionBidAdapter.js +1 -1
  174. package/dist/tripleliftBidAdapter.js +1 -1
  175. package/dist/ttdBidAdapter.js +1 -1
  176. package/dist/twistDigitalBidAdapter.js +1 -1
  177. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  178. package/dist/uid2IdSystem.js +1 -1
  179. package/dist/underdogmediaBidAdapter.js +1 -1
  180. package/dist/undertoneBidAdapter.js +1 -1
  181. package/dist/unrulyBidAdapter.js +1 -1
  182. package/dist/vidazooBidAdapter.js +1 -1
  183. package/dist/videobyteBidAdapter.js +1 -1
  184. package/dist/visiblemeasuresBidAdapter.js +1 -1
  185. package/dist/visxBidAdapter.js +1 -1
  186. package/dist/vuukleBidAdapter.js +1 -1
  187. package/dist/widespaceBidAdapter.js +1 -1
  188. package/dist/winrBidAdapter.js +1 -1
  189. package/dist/yahooAdsBidAdapter.js +1 -1
  190. package/dist/yieldmoBidAdapter.js +1 -1
  191. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  192. package/dist/zeta_global_sspAnalyticsAdapter.js +1 -1
  193. package/integrationExamples/gpt/raynRtdProvider_example.html +1 -0
  194. package/libraries/adagioUtils/adagioUtils.js +35 -0
  195. package/libraries/appnexusUtils/anUtils.js +1 -0
  196. package/libraries/autoplayDetection/autoplay.js +8 -1
  197. package/libraries/ortbConverter/converter.js +1 -1
  198. package/libraries/teqblazeUtils/bidderUtils.js +253 -0
  199. package/modules/.submodules.json +1 -0
  200. package/modules/acuityadsBidAdapter.js +5 -203
  201. package/modules/adagioBidAdapter.js +1 -17
  202. package/modules/adagioRtdProvider.js +41 -51
  203. package/modules/adagioRtdProvider.md +1 -0
  204. package/modules/admanBidAdapter.js +31 -188
  205. package/modules/adprimeBidAdapter.js +28 -165
  206. package/modules/axisBidAdapter.js +33 -165
  207. package/modules/beyondmediaBidAdapter.js +5 -189
  208. package/modules/bliinkBidAdapter.js +3 -31
  209. package/modules/boldwinBidAdapter.js +21 -159
  210. package/modules/ceeIdSystem.js +1 -1
  211. package/modules/compassBidAdapter.js +5 -198
  212. package/modules/contentexchangeBidAdapter.js +5 -200
  213. package/modules/conversantBidAdapter.js +1 -0
  214. package/modules/dailymotionBidAdapter.js +1 -1
  215. package/modules/e_volutionBidAdapter.js +4 -186
  216. package/modules/emtvBidAdapter.js +5 -198
  217. package/modules/globalsunBidAdapter.js +5 -199
  218. package/modules/id5IdSystem.js +31 -2
  219. package/modules/id5IdSystem.md +67 -2
  220. package/modules/iqzoneBidAdapter.js +5 -224
  221. package/modules/kiviadsBidAdapter.js +5 -199
  222. package/modules/krushmediaBidAdapter.js +25 -143
  223. package/modules/loyalBidAdapter.js +4 -178
  224. package/modules/lunamediahbBidAdapter.js +5 -118
  225. package/modules/mathildeadsBidAdapter.js +5 -198
  226. package/modules/mgidXBidAdapter.js +14 -209
  227. package/modules/mobfoxpbBidAdapter.js +4 -135
  228. package/modules/mobianRtdProvider.js +52 -0
  229. package/modules/mobianRtdProvider.md +11 -0
  230. package/modules/nobidAnalyticsAdapter.js +2 -3
  231. package/modules/novatiqIdSystem.md +2 -3
  232. package/modules/ozoneBidAdapter.js +117 -58
  233. package/modules/paapi.js +2 -1
  234. package/modules/pgamsspBidAdapter.js +5 -240
  235. package/modules/playdigoBidAdapter.js +4 -186
  236. package/modules/prebidServerBidAdapter/index.js +9 -2
  237. package/modules/pubCircleBidAdapter.js +5 -218
  238. package/modules/pubmaticAnalyticsAdapter.js +21 -8
  239. package/modules/pubxaiAnalyticsAdapter.js +1 -5
  240. package/modules/qtBidAdapter.js +5 -224
  241. package/modules/raynRtdProvider.js +36 -3
  242. package/modules/richaudienceBidAdapter.js +375 -0
  243. package/modules/richaudienceBidAdapter.md +1 -1
  244. package/modules/seedtagBidAdapter.js +1 -0
  245. package/modules/setupadBidAdapter.js +76 -153
  246. package/modules/setupadBidAdapter.md +1 -1
  247. package/modules/smaatoBidAdapter.js +17 -6
  248. package/modules/smartytechBidAdapter.js +7 -2
  249. package/modules/topicsFpdModule.js +1 -1
  250. package/modules/uid2IdSystem.js +0 -1
  251. package/modules/uid2IdSystem_shared.js +0 -1
  252. package/modules/visiblemeasuresBidAdapter.js +5 -199
  253. package/modules/zeta_global_sspAnalyticsAdapter.js +8 -4
  254. package/package.json +1 -1
  255. package/src/auction.js +5 -63
  256. package/src/utils/focusTimeout.js +41 -0
  257. package/src/utils/ttlCollection.js +2 -1
  258. package/src/utils.js +42 -0
  259. package/src/videoCache.js +72 -0
  260. package/test/mocks/videoCacheStub.js +1 -1
  261. package/test/spec/auctionmanager_spec.js +16 -1
  262. package/test/spec/libraries/teqblazeUtils/bidderUtils_spec.js +519 -0
  263. package/test/spec/modules/acuityadsBidAdapter_spec.js +79 -43
  264. package/test/spec/modules/adagioRtdProvider_spec.js +62 -1
  265. package/test/spec/modules/admanBidAdapter_spec.js +370 -247
  266. package/test/spec/modules/adprimeBidAdapter_spec.js +225 -78
  267. package/test/spec/modules/axisBidAdapter_spec.js +78 -14
  268. package/test/spec/modules/beyondmediaBidAdapter_spec.js +80 -18
  269. package/test/spec/modules/bliinkBidAdapter_spec.js +8 -2
  270. package/test/spec/modules/boldwinBidAdapter_spec.js +221 -75
  271. package/test/spec/modules/compassBidAdapter_spec.js +130 -16
  272. package/test/spec/modules/contentexchangeBidAdapter_spec.js +134 -21
  273. package/test/spec/modules/conversantBidAdapter_spec.js +7 -0
  274. package/test/spec/modules/dailymotionBidAdapter_spec.js +3 -3
  275. package/test/spec/modules/e_volutionBidAdapter_spec.js +65 -3
  276. package/test/spec/modules/emtvBidAdapter_spec.js +131 -16
  277. package/test/spec/modules/globalsunBidAdapter_spec.js +130 -16
  278. package/test/spec/modules/id5IdSystem_spec.js +79 -3
  279. package/test/spec/modules/iqzoneBidAdapter_spec.js +66 -12
  280. package/test/spec/modules/kiviadsBidAdapter_spec.js +131 -20
  281. package/test/spec/modules/krushmediaBidAdapter_spec.js +272 -90
  282. package/test/spec/modules/loyalBidAdapter_spec.js +114 -14
  283. package/test/spec/modules/lunamediahbBidAdapter_spec.js +221 -87
  284. package/test/spec/modules/mathildeadsBidAdapter_spec.js +87 -18
  285. package/test/spec/modules/mgidXBidAdapter_spec.js +11 -3
  286. package/test/spec/modules/mobfoxpbBidAdapter_spec.js +229 -91
  287. package/test/spec/modules/mobianRtdProvider_spec.js +107 -0
  288. package/test/spec/modules/ozoneBidAdapter_spec.js +192 -22
  289. package/test/spec/modules/paapi_spec.js +5 -5
  290. package/test/spec/modules/pgamsspBidAdapter_spec.js +83 -16
  291. package/test/spec/modules/playdigoBidAdapter_spec.js +38 -9
  292. package/test/spec/modules/prebidServerBidAdapter_spec.js +14 -0
  293. package/test/spec/modules/pubCircleBidAdapter_spec.js +82 -17
  294. package/test/spec/modules/pubmaticAnalyticsAdapter_spec.js +52 -5
  295. package/test/spec/modules/qtBidAdapter_spec.js +15 -3
  296. package/test/spec/modules/raynRtdProvider_spec.js +25 -0
  297. package/test/spec/modules/richaudienceBidAdapter_spec.js +1304 -0
  298. package/test/spec/modules/seedtagBidAdapter_spec.js +2 -0
  299. package/test/spec/modules/setupadBidAdapter_spec.js +139 -97
  300. package/test/spec/modules/smaatoBidAdapter_spec.js +27 -0
  301. package/test/spec/modules/smartytechBidAdapter_spec.js +5 -1
  302. package/test/spec/modules/topicsFpdModule_spec.js +43 -59
  303. package/test/spec/modules/visiblemeasuresBidAdapter_spec.js +130 -16
  304. package/test/spec/modules/zeta_global_sspAnalyticsAdapter_spec.js +4 -0
  305. package/test/spec/ortbConverter/converter_spec.js +7 -3
  306. package/test/spec/unit/utils/focusTimeout_spec.js +60 -0
  307. package/test/spec/videoCache_spec.js +56 -53
package/src/auction.js CHANGED
@@ -82,7 +82,7 @@ import {
82
82
  } from './utils.js';
83
83
  import {getPriceBucketString} from './cpmBucketManager.js';
84
84
  import {getNativeTargeting, isNativeResponse, setNativeResponseProperties} from './native.js';
85
- import {getCacheUrl, store} from './videoCache.js';
85
+ import {batchAndStore} from './videoCache.js';
86
86
  import {Renderer} from './Renderer.js';
87
87
  import {config} from './config.js';
88
88
  import {userSync} from './userSync.js';
@@ -94,7 +94,7 @@ import {auctionManager} from './auctionManager.js';
94
94
  import {bidderSettings} from './bidderSettings.js';
95
95
  import * as events from './events.js';
96
96
  import adapterManager from './adapterManager.js';
97
- import { EVENTS, GRANULARITY_OPTIONS, JSON_MAPPING, REJECTION_REASON, S2S, TARGETING_KEYS } from './constants.js';
97
+ import {EVENTS, GRANULARITY_OPTIONS, JSON_MAPPING, REJECTION_REASON, S2S, TARGETING_KEYS} from './constants.js';
98
98
  import {defer, GreedyPromise} from './utils/promise.js';
99
99
  import {useMetrics} from './utils/perfMetrics.js';
100
100
  import {adjustCpm} from './utils/cpm.js';
@@ -580,68 +580,10 @@ function tryAddVideoBid(auctionInstance, bidResponse, afterBidAdded, {index = au
580
580
  }
581
581
  }
582
582
 
583
- const _storeInCache = (batch) => {
584
- store(batch.map(entry => entry.bidResponse), function (error, cacheIds) {
585
- cacheIds.forEach((cacheId, i) => {
586
- const { auctionInstance, bidResponse, afterBidAdded } = batch[i];
587
- if (error) {
588
- logWarn(`Failed to save to the video cache: ${error}. Video bid must be discarded.`);
589
- } else {
590
- if (cacheId.uuid === '') {
591
- logWarn(`Supplied video cache key was already in use by Prebid Cache; caching attempt was rejected. Video bid must be discarded.`);
592
- } else {
593
- bidResponse.videoCacheKey = cacheId.uuid;
594
- if (!bidResponse.vastUrl) {
595
- bidResponse.vastUrl = getCacheUrl(bidResponse.videoCacheKey);
596
- }
597
- addBidToAuction(auctionInstance, bidResponse);
598
- afterBidAdded();
599
- }
600
- }
601
- });
602
- });
603
- };
604
-
605
- const storeInCache = FEATURES.VIDEO ? _storeInCache : () => {};
606
-
607
- let batchSize, batchTimeout;
608
- config.getConfig('cache', (cacheConfig) => {
609
- batchSize = typeof cacheConfig.cache.batchSize === 'number' && cacheConfig.cache.batchSize > 0
610
- ? cacheConfig.cache.batchSize
611
- : 1;
612
- batchTimeout = typeof cacheConfig.cache.batchTimeout === 'number' && cacheConfig.cache.batchTimeout > 0
613
- ? cacheConfig.cache.batchTimeout
614
- : 0;
615
- });
616
-
617
- export const batchingCache = (timeout = setTimeout, cache = storeInCache) => {
618
- let batches = [[]];
619
- let debouncing = false;
620
- const noTimeout = cb => cb();
621
-
622
- return function(auctionInstance, bidResponse, afterBidAdded) {
623
- const batchFunc = batchTimeout > 0 ? timeout : noTimeout;
624
- if (batches[batches.length - 1].length >= batchSize) {
625
- batches.push([]);
626
- }
627
-
628
- batches[batches.length - 1].push({auctionInstance, bidResponse, afterBidAdded});
629
-
630
- if (!debouncing) {
631
- debouncing = true;
632
- batchFunc(() => {
633
- batches.forEach(cache);
634
- batches = [[]];
635
- debouncing = false;
636
- }, batchTimeout);
637
- }
638
- }
639
- };
640
-
641
- const batchAndStore = batchingCache();
642
-
643
583
  export const callPrebidCache = hook('async', function(auctionInstance, bidResponse, afterBidAdded, videoMediaType) {
644
- batchAndStore(auctionInstance, bidResponse, afterBidAdded);
584
+ if (FEATURES.VIDEO) {
585
+ batchAndStore(auctionInstance, bidResponse, afterBidAdded);
586
+ }
645
587
  }, 'callPrebidCache');
646
588
 
647
589
  /**
@@ -0,0 +1,41 @@
1
+ let outOfFocusStart;
2
+ let timeOutOfFocus = 0;
3
+ let suspendedTimeouts = [];
4
+
5
+ document.addEventListener('visibilitychange', () => {
6
+ if (document.hidden) {
7
+ outOfFocusStart = Date.now()
8
+ } else {
9
+ timeOutOfFocus += Date.now() - outOfFocusStart
10
+ suspendedTimeouts.forEach(({ callback, startTime, setTimerId }) => setTimerId(setFocusTimeout(callback, timeOutOfFocus - startTime)()))
11
+ outOfFocusStart = null;
12
+ }
13
+ });
14
+
15
+ /**
16
+ * Wraps native setTimeout function in order to count time only when page is focused
17
+ *
18
+ * @param {function(*): ()} [callback] - A function that will be invoked after passed time
19
+ * @param {number} [milliseconds] - Minimum duration (in milliseconds) that the callback will be executed after
20
+ * @returns {function(*): (number)} - Getter function for current timer id
21
+ */
22
+ export default function setFocusTimeout(callback, milliseconds) {
23
+ const startTime = timeOutOfFocus;
24
+ let timerId = setTimeout(() => {
25
+ if (timeOutOfFocus === startTime && outOfFocusStart == null) {
26
+ callback();
27
+ } else if (outOfFocusStart != null) {
28
+ // case when timeout ended during page is out of focus
29
+ suspendedTimeouts.push({
30
+ callback,
31
+ startTime,
32
+ setTimerId(newId) {
33
+ timerId = newId;
34
+ }
35
+ })
36
+ } else {
37
+ timerId = setFocusTimeout(callback, timeOutOfFocus - startTime)();
38
+ }
39
+ }, milliseconds);
40
+ return () => timerId;
41
+ }
@@ -1,5 +1,6 @@
1
1
  import {GreedyPromise} from './promise.js';
2
2
  import {binarySearch, logError, timestamp} from '../utils.js';
3
+ import setFocusTimeout from './focusTimeout.js';
3
4
 
4
5
  /**
5
6
  * Create a set-like collection that automatically forgets items after a certain time.
@@ -46,7 +47,7 @@ export function ttlCollection(
46
47
  if (pendingPurge.length > 0) {
47
48
  const now = timestamp();
48
49
  nextPurge = Math.max(now, pendingPurge[0].expiry + slack);
49
- task = setTimeout(() => {
50
+ task = setFocusTimeout(() => {
50
51
  const now = timestamp();
51
52
  let cnt = 0;
52
53
  for (const entry of pendingPurge) {
package/src/utils.js CHANGED
@@ -661,6 +661,21 @@ export function isSafeFrameWindow() {
661
661
  return !!(ws.$sf && ws.$sf.ext);
662
662
  }
663
663
 
664
+ /**
665
+ * Returns the result of calling the function $sf.ext.geom() if it exists
666
+ * @see https://iabtechlab.com/wp-content/uploads/2016/03/SafeFrames_v1.1_final.pdf — 5.4 Function $sf.ext.geom
667
+ * @returns {Object | undefined} geometric information about the container
668
+ */
669
+ export function getSafeframeGeometry() {
670
+ try {
671
+ const ws = getWindowSelf();
672
+ return (typeof ws.$sf.ext.geom === 'function') ? ws.$sf.ext.geom() : undefined;
673
+ } catch (e) {
674
+ logError('Error getting SafeFrame geometry', e);
675
+ return undefined;
676
+ }
677
+ }
678
+
664
679
  export function isSafariBrowser() {
665
680
  return /^((?!chrome|android|crios|fxios).)*safari/i.test(navigator.userAgent);
666
681
  }
@@ -693,6 +708,33 @@ export function getPerformanceNow() {
693
708
  return (window.performance && window.performance.now && window.performance.now()) || 0;
694
709
  }
695
710
 
711
+ /**
712
+ * Retuns the difference between `timing.domLoading` and `timing.navigationStart`.
713
+ * This function uses the deprecated `Performance.timing` API and should be removed in future.
714
+ * It has not been updated yet because it is still used in some modules.
715
+ * @deprecated
716
+ * @param {Window} w The window object used to perform the api call. default to window.self
717
+ * @returns {number}
718
+ */
719
+ export function getDomLoadingDuration(w) {
720
+ let domLoadingDuration = -1;
721
+
722
+ w = w || getWindowSelf();
723
+
724
+ const performance = w.performance;
725
+
726
+ if (w.performance?.timing) {
727
+ if (w.performance.timing.navigationStart > 0) {
728
+ const val = performance.timing.domLoading - performance.timing.navigationStart;
729
+ if (val > 0) {
730
+ domLoadingDuration = val;
731
+ }
732
+ }
733
+ }
734
+
735
+ return domLoadingDuration;
736
+ }
737
+
696
738
  /**
697
739
  * When the deviceAccess flag config option is false, no cookies should be read or set
698
740
  * @returns {boolean}
package/src/videoCache.js CHANGED
@@ -12,6 +12,8 @@
12
12
  import {ajaxBuilder} from './ajax.js';
13
13
  import {config} from './config.js';
14
14
  import {auctionManager} from './auctionManager.js';
15
+ import {logError, logWarn} from './utils.js';
16
+ import {addBidToAuction} from './auction.js';
15
17
 
16
18
  /**
17
19
  * Might be useful to be configurable in the future
@@ -159,3 +161,73 @@ export function store(bids, done, getAjax = ajaxBuilder) {
159
161
  export function getCacheUrl(id) {
160
162
  return `${config.getConfig('cache.url')}?uuid=${id}`;
161
163
  }
164
+
165
+ export const _internal = {
166
+ store
167
+ }
168
+
169
+ export function storeBatch(batch) {
170
+ const bids = batch.map(entry => entry.bidResponse)
171
+ function err(msg) {
172
+ logError(`Failed to save to the video cache: ${msg}. Video bids will be discarded:`, bids)
173
+ }
174
+ _internal.store(bids, function (error, cacheIds) {
175
+ if (error) {
176
+ err(error)
177
+ } else if (batch.length !== cacheIds.length) {
178
+ logError(`expected ${batch.length} cache IDs, got ${cacheIds.length} instead`)
179
+ } else {
180
+ cacheIds.forEach((cacheId, i) => {
181
+ const {auctionInstance, bidResponse, afterBidAdded} = batch[i];
182
+ if (cacheId.uuid === '') {
183
+ logWarn(`Supplied video cache key was already in use by Prebid Cache; caching attempt was rejected. Video bid must be discarded.`);
184
+ } else {
185
+ bidResponse.videoCacheKey = cacheId.uuid;
186
+ if (!bidResponse.vastUrl) {
187
+ bidResponse.vastUrl = getCacheUrl(bidResponse.videoCacheKey);
188
+ }
189
+ addBidToAuction(auctionInstance, bidResponse);
190
+ afterBidAdded();
191
+ }
192
+ });
193
+ }
194
+ });
195
+ };
196
+
197
+ let batchSize, batchTimeout;
198
+ if (FEATURES.VIDEO) {
199
+ config.getConfig('cache', (cacheConfig) => {
200
+ batchSize = typeof cacheConfig.cache.batchSize === 'number' && cacheConfig.cache.batchSize > 0
201
+ ? cacheConfig.cache.batchSize
202
+ : 1;
203
+ batchTimeout = typeof cacheConfig.cache.batchTimeout === 'number' && cacheConfig.cache.batchTimeout > 0
204
+ ? cacheConfig.cache.batchTimeout
205
+ : 0;
206
+ });
207
+ }
208
+
209
+ export const batchingCache = (timeout = setTimeout, cache = storeBatch) => {
210
+ let batches = [[]];
211
+ let debouncing = false;
212
+ const noTimeout = cb => cb();
213
+
214
+ return function (auctionInstance, bidResponse, afterBidAdded) {
215
+ const batchFunc = batchTimeout > 0 ? timeout : noTimeout;
216
+ if (batches[batches.length - 1].length >= batchSize) {
217
+ batches.push([]);
218
+ }
219
+
220
+ batches[batches.length - 1].push({auctionInstance, bidResponse, afterBidAdded});
221
+
222
+ if (!debouncing) {
223
+ debouncing = true;
224
+ batchFunc(() => {
225
+ batches.forEach(cache);
226
+ batches = [[]];
227
+ debouncing = false;
228
+ }, batchTimeout);
229
+ }
230
+ };
231
+ };
232
+
233
+ export const batchAndStore = batchingCache();
@@ -1,4 +1,4 @@
1
- import * as videoCache from 'src/videoCache.js';
1
+ import {_internal as videoCache} from 'src/videoCache.js';
2
2
 
3
3
  /**
4
4
  * Function which can be called from unit tests to stub out the video cache.
@@ -12,7 +12,7 @@ import * as auctionModule from 'src/auction.js';
12
12
  import { registerBidder } from 'src/adapters/bidderFactory.js';
13
13
  import { createBid } from 'src/bidfactory.js';
14
14
  import { config } from 'src/config.js';
15
- import * as store from 'src/videoCache.js';
15
+ import {_internal as store} from 'src/videoCache.js';
16
16
  import * as ajaxLib from 'src/ajax.js';
17
17
  import {find} from 'src/polyfill.js';
18
18
  import { server } from 'test/mocks/xhr.js';
@@ -27,6 +27,7 @@ import {PrebidServer} from '../../modules/prebidServerBidAdapter/index.js';
27
27
  import '../../modules/currency.js'
28
28
  import { setConfig as setCurrencyConfig } from '../../modules/currency.js';
29
29
  import { REJECTION_REASON } from '../../src/constants.js';
30
+ import { setDocumentHidden } from './unit/utils/focusTimeout_spec.js';
30
31
 
31
32
  /**
32
33
  * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest
@@ -888,6 +889,20 @@ describe('auctionmanager.js', function () {
888
889
  })
889
890
  });
890
891
 
892
+ it('are not dropped after `minBidCacheTTL` seconds if the page was hidden', () => {
893
+ auction.callBids();
894
+ config.setConfig({
895
+ minBidCacheTTL: 10
896
+ });
897
+ return auction.end.then(() => {
898
+ expect(auctionManager.getNoBids().length).to.eql(1);
899
+ setDocumentHidden(true);
900
+ clock.tick(10 * 10000);
901
+ setDocumentHidden(false);
902
+ expect(auctionManager.getNoBids().length).to.eql(1);
903
+ })
904
+ });
905
+
891
906
  Object.entries({
892
907
  'bids': {
893
908
  bd: [{