prebid.js 7.4.0 → 7.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.circleci/config.yml +11 -6
- package/dist/1plusXRtdProvider.js +1 -0
- package/dist/33acrossBidAdapter.js +1 -1
- package/dist/adagioBidAdapter.js +1 -1
- package/dist/adbookpspBidAdapter.js +1 -1
- package/dist/adgenerationBidAdapter.js +1 -1
- package/dist/adnuntiusBidAdapter.js +1 -1
- package/dist/adoceanBidAdapter.js +1 -1
- package/dist/adotBidAdapter.js +1 -1
- package/dist/adrelevantisBidAdapter.js +1 -1
- package/dist/adrinoBidAdapter.js +1 -1
- package/dist/adtelligentBidAdapter.js +1 -1
- package/dist/adxcgBidAdapter.js +1 -1
- package/dist/ajaBidAdapter.js +1 -1
- package/dist/amxBidAdapter.js +1 -1
- package/dist/amxIdSystem.js +1 -1
- package/dist/appierAnalyticsAdapter.js +1 -1
- package/dist/appnexusBidAdapter.js +1 -1
- package/dist/asoBidAdapter.js +1 -1
- package/dist/atsAnalyticsAdapter.js +1 -1
- package/dist/axonixBidAdapter.js +1 -1
- package/dist/bidglassBidAdapter.js +1 -1
- package/dist/big-richmediaBidAdapter.js +1 -1
- package/dist/bliinkBidAdapter.js +1 -1
- package/dist/bridgewellBidAdapter.js +1 -1
- package/dist/brightMountainMediaBidAdapter.js +1 -1
- package/dist/byDataAnalyticsAdapter.js +1 -1
- package/dist/concertBidAdapter.js +1 -1
- package/dist/connectadBidAdapter.js +1 -1
- package/dist/consumableBidAdapter.js +1 -1
- package/dist/conversantBidAdapter.js +1 -1
- package/dist/craftBidAdapter.js +1 -1
- package/dist/criteoBidAdapter.js +1 -1
- package/dist/currency.js +1 -1
- package/dist/dspxBidAdapter.js +1 -1
- package/dist/eplanningBidAdapter.js +1 -1
- package/dist/finativeBidAdapter.js +1 -1
- package/dist/gdprEnforcement.js +1 -1
- package/dist/glimpseBidAdapter.js +1 -1
- package/dist/gmosspBidAdapter.js +1 -1
- package/dist/goldbachBidAdapter.js +1 -1
- package/dist/gridBidAdapter.js +1 -1
- package/dist/gridNMBidAdapter.js +1 -1
- package/dist/gumgumBidAdapter.js +1 -1
- package/dist/h12mediaBidAdapter.js +1 -1
- package/dist/hadronIdSystem.js +1 -1
- package/dist/hadronRtdProvider.js +1 -1
- package/dist/id5IdSystem.js +1 -1
- package/dist/imRtdProvider.js +1 -1
- package/dist/impactifyBidAdapter.js +1 -1
- package/dist/improvedigitalBidAdapter.js +1 -1
- package/dist/inmarBidAdapter.js +1 -1
- package/dist/insticatorBidAdapter.js +1 -1
- package/dist/ixBidAdapter.js +1 -1
- package/dist/jixieBidAdapter.js +1 -1
- package/dist/justpremiumBidAdapter.js +1 -1
- package/dist/kargoAnalyticsAdapter.js +1 -1
- package/dist/konduitAnalyticsAdapter.js +1 -1
- package/dist/kueezBidAdapter.js +1 -1
- package/dist/lassoBidAdapter.js +1 -1
- package/dist/liveyieldAnalyticsAdapter.js +1 -1
- package/dist/logicadBidAdapter.js +1 -1
- package/dist/loglyliftBidAdapter.js +1 -1
- package/dist/malltvAnalyticsAdapter.js +1 -1
- package/dist/marsmediaBidAdapter.js +1 -1
- package/dist/mediafuseBidAdapter.js +1 -1
- package/dist/mediasquareBidAdapter.js +1 -1
- package/dist/mgidBidAdapter.js +1 -1
- package/dist/minutemediaBidAdapter.js +1 -1
- package/dist/naveggIdSystem.js +1 -1
- package/dist/newspassidBidAdapter.js +1 -0
- package/dist/nextMillenniumBidAdapter.js +1 -1
- package/dist/not-for-prod/prebid.js +131 -128
- package/dist/oguryBidAdapter.js +1 -1
- package/dist/onetagBidAdapter.js +1 -1
- package/dist/ooloAnalyticsAdapter.js +1 -1
- package/dist/outbrainBidAdapter.js +1 -1
- package/dist/parrableIdSystem.js +1 -1
- package/dist/pixfutureBidAdapter.js +1 -1
- package/dist/prebid-core.js +1 -1
- package/dist/prebidServerBidAdapter.js +1 -1
- package/dist/priceFloors.js +1 -1
- package/dist/pubCommonId.js +1 -1
- package/dist/publinkIdSystem.js +1 -1
- package/dist/pubmaticBidAdapter.js +1 -1
- package/dist/pubwiseAnalyticsAdapter.js +1 -1
- package/dist/pubxaiAnalyticsAdapter.js +1 -1
- package/dist/pxyzBidAdapter.js +1 -1
- package/dist/quantcastBidAdapter.js +1 -1
- package/dist/rasBidAdapter.js +1 -0
- package/dist/readpeakBidAdapter.js +1 -1
- package/dist/relaidoBidAdapter.js +1 -1
- package/dist/rhythmoneBidAdapter.js +1 -1
- package/dist/riseBidAdapter.js +1 -1
- package/dist/rubiconAnalyticsAdapter.js +1 -1
- package/dist/rubiconBidAdapter.js +1 -1
- package/dist/seedingAllianceBidAdapter.js +1 -1
- package/dist/seedtagBidAdapter.js +1 -1
- package/dist/sharedIdSystem.js +1 -1
- package/dist/sharethroughAnalyticsAdapter.js +1 -1
- package/dist/sharethroughBidAdapter.js +1 -1
- package/dist/shinezBidAdapter.js +1 -1
- package/dist/smaatoBidAdapter.js +1 -1
- package/dist/smartadserverBidAdapter.js +1 -1
- package/dist/smartxBidAdapter.js +1 -1
- package/dist/smilewantedBidAdapter.js +1 -1
- package/dist/sonobiBidAdapter.js +1 -1
- package/dist/sovrnAnalyticsAdapter.js +1 -1
- package/dist/sovrnBidAdapter.js +1 -1
- package/dist/sspBCBidAdapter.js +1 -1
- package/dist/sublimeBidAdapter.js +1 -1
- package/dist/synacormediaBidAdapter.js +1 -1
- package/dist/taboolaBidAdapter.js +1 -1
- package/dist/targetVideoBidAdapter.js +1 -1
- package/dist/teadsBidAdapter.js +1 -1
- package/dist/trionBidAdapter.js +1 -1
- package/dist/tripleliftBidAdapter.js +1 -1
- package/dist/ttdBidAdapter.js +1 -1
- package/dist/ucfunnelAnalyticsAdapter.js +1 -1
- package/dist/underdogmediaBidAdapter.js +1 -1
- package/dist/undertoneBidAdapter.js +1 -1
- package/dist/userId.js +1 -1
- package/dist/vidazooBidAdapter.js +1 -1
- package/dist/videobyteBidAdapter.js +1 -1
- package/dist/visxBidAdapter.js +1 -1
- package/dist/vuukleBidAdapter.js +1 -1
- package/dist/widespaceBidAdapter.js +1 -1
- package/dist/winrBidAdapter.js +1 -1
- package/dist/yahoosspBidAdapter.js +1 -1
- package/dist/yieldmoBidAdapter.js +1 -1
- package/dist/yieldoneAnalyticsAdapter.js +1 -1
- package/integrationExamples/gpt/1plusXRtdProviderExample.html +112 -0
- package/karma.conf.maker.js +3 -1
- package/modules/.submodules.json +2 -1
- package/modules/1plusXRtdProvider.js +251 -0
- package/modules/1plusXRtdProvider.md +65 -0
- package/modules/adgenerationBidAdapter.js +24 -1
- package/modules/adnuntiusBidAdapter.js +26 -8
- package/modules/adoceanBidAdapter.js +10 -3
- package/modules/adotBidAdapter.js +13 -4
- package/modules/adrinoBidAdapter.js +10 -2
- package/modules/adrinoBidAdapter.md +6 -0
- package/modules/adtelligentBidAdapter.js +2 -1
- package/modules/appnexusBidAdapter.js +3 -3
- package/modules/atsAnalyticsAdapter.js +4 -5
- package/modules/big-richmediaBidAdapter.js +3 -3
- package/modules/bliinkBidAdapter.js +120 -193
- package/modules/bliinkBidAdapter.md +2 -5
- package/modules/byDataAnalyticsAdapter.js +172 -74
- package/modules/byDataAnalyticsAdapter.md +5 -6
- package/modules/consumableBidAdapter.js +21 -1
- package/modules/criteoBidAdapter.js +7 -1
- package/modules/currency.js +2 -2
- package/modules/cwireBidAdapter.md +1 -1
- package/modules/eplanningBidAdapter.js +82 -97
- package/modules/gdprEnforcement.js +8 -14
- package/modules/gridNMBidAdapter.js +45 -4
- package/modules/hadronAnalyticsAdapter.md +5 -5
- package/modules/hadronIdSystem.js +18 -5
- package/modules/hadronIdSystem.md +15 -11
- package/modules/hadronRtdProvider.js +14 -1
- package/modules/hadronRtdProvider.md +17 -13
- package/modules/imRtdProvider.js +0 -8
- package/modules/impactifyBidAdapter.js +6 -2
- package/modules/ixBidAdapter.js +133 -23
- package/modules/ixBidAdapter.md +2 -5
- package/modules/jixieBidAdapter.js +10 -10
- package/modules/kargoAnalyticsAdapter.js +88 -6
- package/modules/kargoAnalyticsAdapter.md +33 -0
- package/modules/minutemediaBidAdapter.js +1 -0
- package/modules/naveggIdSystem.js +1 -12
- package/modules/newspassidBidAdapter.js +649 -0
- package/modules/nextMillenniumBidAdapter.js +17 -1
- package/modules/nextMillenniumBidAdapter.md +1 -1
- package/modules/oguryBidAdapter.js +2 -0
- package/modules/onetagBidAdapter.js +44 -7
- package/modules/prebidServerBidAdapter/index.js +7 -0
- package/modules/priceFloors.js +1 -1
- package/modules/pubCommonId.js +1 -2
- package/modules/pubxaiAnalyticsAdapter.js +6 -1
- package/modules/rasBidAdapter.js +149 -0
- package/modules/rasBidAdapter.md +50 -0
- package/modules/rubiconBidAdapter.js +5 -0
- package/modules/seedingAllianceBidAdapter.js +3 -0
- package/modules/seedtagBidAdapter.js +37 -1
- package/modules/sharedIdSystem.js +11 -5
- package/modules/sharethroughBidAdapter.js +9 -24
- package/modules/taboolaBidAdapter.js +1 -1
- package/modules/taboolaBidAdapter.md +3 -3
- package/modules/targetVideoBidAdapter.js +18 -0
- package/modules/userId/index.js +39 -21
- package/package.json +1 -1
- package/src/auction.js +6 -5
- package/src/consentHandler.js +11 -11
- package/src/debugging.js +5 -3
- package/src/hook.js +2 -2
- package/src/storageManager.js +4 -5
- package/src/utils/promise.js +96 -21
- package/src/utils.js +3 -2
- package/test/helpers/consentData.js +2 -1
- package/test/spec/auctionmanager_spec.js +1 -6
- package/test/spec/debugging_spec.js +2 -2
- package/test/spec/modules/1plusXRtdProvider_spec.js +430 -0
- package/test/spec/modules/adgenerationBidAdapter_spec.js +52 -4
- package/test/spec/modules/adnuntiusBidAdapter_spec.js +126 -14
- package/test/spec/modules/adoceanBidAdapter_spec.js +4 -1
- package/test/spec/modules/adotBidAdapter_spec.js +12 -9
- package/test/spec/modules/adrinoBidAdapter_spec.js +22 -0
- package/test/spec/modules/appnexusBidAdapter_spec.js +165 -156
- package/test/spec/modules/bliinkBidAdapter_spec.js +323 -136
- package/test/spec/modules/byDataAnalyticsAdapter_spec.js +74 -24
- package/test/spec/modules/consumableBidAdapter_spec.js +122 -1
- package/test/spec/modules/criteoBidAdapter_spec.js +15 -5
- package/test/spec/modules/eplanningBidAdapter_spec.js +58 -18
- package/test/spec/modules/gdprEnforcement_spec.js +53 -100
- package/test/spec/modules/gridNMBidAdapter_spec.js +32 -0
- package/test/spec/modules/hadronIdSystem_spec.js +2 -2
- package/test/spec/modules/idxIdSystem_spec.js +1 -1
- package/test/spec/modules/imRtdProvider_spec.js +0 -1
- package/test/spec/modules/ixBidAdapter_spec.js +212 -5
- package/test/spec/modules/jixieBidAdapter_spec.js +8 -8
- package/test/spec/modules/kargoAnalyticsAdapter_spec.js +42 -0
- package/test/spec/modules/minutemediaBidAdapter_spec.js +3 -0
- package/test/spec/modules/newspassidBidAdapter_spec.js +1793 -0
- package/test/spec/modules/nextMillenniumBidAdapter_spec.js +20 -0
- package/test/spec/modules/onetagBidAdapter_spec.js +53 -4
- package/test/spec/modules/parrableIdSystem_spec.js +2 -1
- package/test/spec/modules/prebidServerBidAdapter_spec.js +20 -0
- package/test/spec/modules/pubxaiAnalyticsAdapter_spec.js +5 -0
- package/test/spec/modules/rasBidAdapter_spec.js +190 -0
- package/test/spec/modules/rubiconBidAdapter_spec.js +27 -0
- package/test/spec/modules/seedtagBidAdapter_spec.js +29 -0
- package/test/spec/modules/sharethroughBidAdapter_spec.js +4 -4
- package/test/spec/modules/taboolaBidAdapter_spec.js +1 -1
- package/test/spec/modules/targetVideoBidAdapter_spec.js +43 -0
- package/test/spec/modules/userId_spec.js +15 -2
- package/test/spec/unit/pbjs_api_spec.js +1 -5
- package/test/spec/unit/utils/promise_spec.js +283 -38
- package/test/helpers/syncPromise.js +0 -71
package/modules/userId/index.js
CHANGED
|
@@ -152,7 +152,7 @@ import {
|
|
|
152
152
|
isEmpty
|
|
153
153
|
} from '../../src/utils.js';
|
|
154
154
|
import {getPPID as coreGetPPID} from '../../src/adserver.js';
|
|
155
|
-
import {
|
|
155
|
+
import {defer, GreedyPromise} from '../../src/utils/promise.js';
|
|
156
156
|
import {hasPurpose1Consent} from '../../src/utils/gpdr.js';
|
|
157
157
|
|
|
158
158
|
const MODULE_NAME = 'User ID';
|
|
@@ -504,15 +504,11 @@ function addIdDataToAdUnitBids(adUnits, submodules) {
|
|
|
504
504
|
});
|
|
505
505
|
}
|
|
506
506
|
|
|
507
|
-
function delayFor(ms) {
|
|
508
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
509
|
-
}
|
|
510
|
-
|
|
511
507
|
const INIT_CANCELED = {};
|
|
512
508
|
|
|
513
|
-
function idSystemInitializer({delay =
|
|
514
|
-
const startInit =
|
|
515
|
-
const startCallbacks =
|
|
509
|
+
function idSystemInitializer({delay = GreedyPromise.timeout} = {}) {
|
|
510
|
+
const startInit = defer();
|
|
511
|
+
const startCallbacks = defer();
|
|
516
512
|
let cancel;
|
|
517
513
|
let initialized = false;
|
|
518
514
|
|
|
@@ -520,8 +516,8 @@ function idSystemInitializer({delay = delayFor} = {}) {
|
|
|
520
516
|
if (cancel != null) {
|
|
521
517
|
cancel.reject(INIT_CANCELED);
|
|
522
518
|
}
|
|
523
|
-
cancel =
|
|
524
|
-
return
|
|
519
|
+
cancel = defer();
|
|
520
|
+
return GreedyPromise.race([promise, cancel.promise]);
|
|
525
521
|
}
|
|
526
522
|
|
|
527
523
|
// grab a reference to global vars so that the promise chains remain isolated;
|
|
@@ -540,7 +536,7 @@ function idSystemInitializer({delay = delayFor} = {}) {
|
|
|
540
536
|
}
|
|
541
537
|
|
|
542
538
|
let done = cancelAndTry(
|
|
543
|
-
|
|
539
|
+
GreedyPromise.all([hooksReady, startInit.promise])
|
|
544
540
|
.then(() => gdprDataHandler.promise)
|
|
545
541
|
.then(checkRefs((consentData) => {
|
|
546
542
|
initSubmodules(initModules, allModules, consentData);
|
|
@@ -549,7 +545,7 @@ function idSystemInitializer({delay = delayFor} = {}) {
|
|
|
549
545
|
.then(checkRefs(() => {
|
|
550
546
|
const modWithCb = initModules.filter(item => isFn(item.callback));
|
|
551
547
|
if (modWithCb.length) {
|
|
552
|
-
return new
|
|
548
|
+
return new GreedyPromise((resolve) => processSubmoduleCallbacks(modWithCb, resolve));
|
|
553
549
|
}
|
|
554
550
|
}))
|
|
555
551
|
);
|
|
@@ -573,7 +569,7 @@ function idSystemInitializer({delay = delayFor} = {}) {
|
|
|
573
569
|
});
|
|
574
570
|
}
|
|
575
571
|
}
|
|
576
|
-
if (refresh) {
|
|
572
|
+
if (refresh && initialized) {
|
|
577
573
|
done = cancelAndTry(
|
|
578
574
|
done
|
|
579
575
|
.catch(() => null)
|
|
@@ -588,7 +584,7 @@ function idSystemInitializer({delay = delayFor} = {}) {
|
|
|
588
584
|
return sm.callback != null;
|
|
589
585
|
});
|
|
590
586
|
if (cbModules.length) {
|
|
591
|
-
return new
|
|
587
|
+
return new GreedyPromise((resolve) => processSubmoduleCallbacks(cbModules, resolve));
|
|
592
588
|
}
|
|
593
589
|
}))
|
|
594
590
|
);
|
|
@@ -621,8 +617,8 @@ function getPPID() {
|
|
|
621
617
|
* @param {Object} reqBidsConfigObj required; This is the same param that's used in pbjs.requestBids.
|
|
622
618
|
* @param {function} fn required; The next function in the chain, used by hook.js
|
|
623
619
|
*/
|
|
624
|
-
export function requestBidsHook(fn, reqBidsConfigObj, {delay =
|
|
625
|
-
|
|
620
|
+
export function requestBidsHook(fn, reqBidsConfigObj, {delay = GreedyPromise.timeout} = {}) {
|
|
621
|
+
GreedyPromise.race([
|
|
626
622
|
getUserIdsAsync(),
|
|
627
623
|
delay(auctionDelay)
|
|
628
624
|
]).then(() => {
|
|
@@ -767,7 +763,16 @@ function refreshUserIds({submoduleNames} = {}, callback) {
|
|
|
767
763
|
*/
|
|
768
764
|
|
|
769
765
|
function getUserIdsAsync() {
|
|
770
|
-
return initIdSystem().then(
|
|
766
|
+
return initIdSystem().then(
|
|
767
|
+
() => getUserIds(),
|
|
768
|
+
(e) =>
|
|
769
|
+
e === INIT_CANCELED
|
|
770
|
+
// there's a pending refresh - because GreedyPromise runs this synchronously, we are now in the middle
|
|
771
|
+
// of canceling the previous init, before the refresh logic has had a chance to run.
|
|
772
|
+
// Use a "normal" Promise to clear the stack and let it complete (or this will just recurse infinitely)
|
|
773
|
+
? Promise.resolve().then(getUserIdsAsync)
|
|
774
|
+
: GreedyPromise.reject(e)
|
|
775
|
+
);
|
|
771
776
|
}
|
|
772
777
|
|
|
773
778
|
/**
|
|
@@ -914,6 +919,8 @@ function updateSubmodules() {
|
|
|
914
919
|
return;
|
|
915
920
|
}
|
|
916
921
|
// do this to avoid reprocessing submodules
|
|
922
|
+
// TODO: the logic does not match the comment - addedSubmodules is always a copy of submoduleRegistry
|
|
923
|
+
// (if it did it would not be correct - it's not enough to find new modules, as others may have been removed or changed)
|
|
917
924
|
const addedSubmodules = submoduleRegistry.filter(i => !find(submodules, j => j.name === i.name));
|
|
918
925
|
|
|
919
926
|
submodules.splice(0, submodules.length);
|
|
@@ -949,6 +956,17 @@ export function attachIdSystem(submodule) {
|
|
|
949
956
|
if (!find(submoduleRegistry, i => i.name === submodule.name)) {
|
|
950
957
|
submoduleRegistry.push(submodule);
|
|
951
958
|
updateSubmodules();
|
|
959
|
+
// TODO: a test case wants this to work even if called after init (the setConfig({userId}))
|
|
960
|
+
// so we trigger a refresh. But is that even possible outside of tests?
|
|
961
|
+
initIdSystem({refresh: true, submoduleNames: [submodule.name]});
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
function normalizePromise(fn) {
|
|
966
|
+
// for public methods that return promises, make sure we return a "normal" one - to avoid
|
|
967
|
+
// exposing confusing stack traces
|
|
968
|
+
return function() {
|
|
969
|
+
return Promise.resolve(fn.apply(this, arguments));
|
|
952
970
|
}
|
|
953
971
|
}
|
|
954
972
|
|
|
@@ -957,7 +975,7 @@ export function attachIdSystem(submodule) {
|
|
|
957
975
|
* so a callback is added to fire after the consentManagement module.
|
|
958
976
|
* @param {{getConfig:function}} config
|
|
959
977
|
*/
|
|
960
|
-
export function init(config, {delay =
|
|
978
|
+
export function init(config, {delay = GreedyPromise.timeout} = {}) {
|
|
961
979
|
ppidSource = undefined;
|
|
962
980
|
submodules = [];
|
|
963
981
|
configRegistry = [];
|
|
@@ -1002,10 +1020,10 @@ export function init(config, {delay = delayFor} = {}) {
|
|
|
1002
1020
|
// exposing getUserIds function in global-name-space so that userIds stored in Prebid can be used by external codes.
|
|
1003
1021
|
(getGlobal()).getUserIds = getUserIds;
|
|
1004
1022
|
(getGlobal()).getUserIdsAsEids = getUserIdsAsEids;
|
|
1005
|
-
(getGlobal()).getEncryptedEidsForSource = getEncryptedEidsForSource;
|
|
1023
|
+
(getGlobal()).getEncryptedEidsForSource = normalizePromise(getEncryptedEidsForSource);
|
|
1006
1024
|
(getGlobal()).registerSignalSources = registerSignalSources;
|
|
1007
|
-
(getGlobal()).refreshUserIds = refreshUserIds;
|
|
1008
|
-
(getGlobal()).getUserIdsAsync = getUserIdsAsync;
|
|
1025
|
+
(getGlobal()).refreshUserIds = normalizePromise(refreshUserIds);
|
|
1026
|
+
(getGlobal()).getUserIdsAsync = normalizePromise(getUserIdsAsync);
|
|
1009
1027
|
(getGlobal()).getUserIdsAsEidBySource = getUserIdsAsEidBySource;
|
|
1010
1028
|
}
|
|
1011
1029
|
|
package/package.json
CHANGED
package/src/auction.js
CHANGED
|
@@ -76,6 +76,7 @@ import {bidderSettings} from './bidderSettings.js';
|
|
|
76
76
|
import * as events from './events.js'
|
|
77
77
|
import adapterManager from './adapterManager.js';
|
|
78
78
|
import CONSTANTS from './constants.json';
|
|
79
|
+
import {GreedyPromise} from './utils/promise.js';
|
|
79
80
|
|
|
80
81
|
const { syncUsers } = userSync;
|
|
81
82
|
|
|
@@ -384,9 +385,9 @@ export function auctionCallbacks(auctionDone, auctionInstance, {index = auctionM
|
|
|
384
385
|
|
|
385
386
|
function waitFor(requestId, result) {
|
|
386
387
|
if (ready[requestId] == null) {
|
|
387
|
-
ready[requestId] =
|
|
388
|
+
ready[requestId] = GreedyPromise.resolve();
|
|
388
389
|
}
|
|
389
|
-
ready[requestId] = ready[requestId].then(() =>
|
|
390
|
+
ready[requestId] = ready[requestId].then(() => GreedyPromise.resolve(result).catch(() => {}))
|
|
390
391
|
}
|
|
391
392
|
|
|
392
393
|
function guard(bidderRequest, fn) {
|
|
@@ -398,9 +399,9 @@ export function auctionCallbacks(auctionDone, auctionInstance, {index = auctionM
|
|
|
398
399
|
const wait = ready[bidderRequest.bidderRequestId];
|
|
399
400
|
const orphanWait = ready['']; // also wait for "orphan" responses that are not associated with any request
|
|
400
401
|
if ((wait != null || orphanWait != null) && timeRemaining > 0) {
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
402
|
+
GreedyPromise.race([
|
|
403
|
+
GreedyPromise.timeout(timeRemaining),
|
|
404
|
+
GreedyPromise.resolve(orphanWait).then(() => wait)
|
|
404
405
|
]).then(fn);
|
|
405
406
|
} else {
|
|
406
407
|
fn();
|
package/src/consentHandler.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {isStr, timestamp} from './utils.js';
|
|
2
|
+
import {defer, GreedyPromise} from './utils/promise.js';
|
|
2
3
|
|
|
3
4
|
export class ConsentHandler {
|
|
4
5
|
#enabled;
|
|
5
6
|
#data;
|
|
6
|
-
#
|
|
7
|
-
#resolve;
|
|
7
|
+
#defer;
|
|
8
8
|
#ready;
|
|
9
9
|
generatedTime;
|
|
10
10
|
|
|
@@ -12,17 +12,17 @@ export class ConsentHandler {
|
|
|
12
12
|
this.reset();
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
#resolve(data) {
|
|
16
|
+
this.#ready = true;
|
|
17
|
+
this.#data = data;
|
|
18
|
+
this.#defer.resolve(data);
|
|
19
|
+
}
|
|
20
|
+
|
|
15
21
|
/**
|
|
16
22
|
* reset this handler (mainly for tests)
|
|
17
23
|
*/
|
|
18
24
|
reset() {
|
|
19
|
-
this.#
|
|
20
|
-
this.#resolve = (data) => {
|
|
21
|
-
this.#ready = true;
|
|
22
|
-
this.#data = data;
|
|
23
|
-
resolve(data);
|
|
24
|
-
};
|
|
25
|
-
});
|
|
25
|
+
this.#defer = defer();
|
|
26
26
|
this.#enabled = false;
|
|
27
27
|
this.#data = null;
|
|
28
28
|
this.#ready = false;
|
|
@@ -56,12 +56,12 @@ export class ConsentHandler {
|
|
|
56
56
|
*/
|
|
57
57
|
get promise() {
|
|
58
58
|
if (this.#ready) {
|
|
59
|
-
return
|
|
59
|
+
return GreedyPromise.resolve(this.#data);
|
|
60
60
|
}
|
|
61
61
|
if (!this.#enabled) {
|
|
62
62
|
this.#resolve(null);
|
|
63
63
|
}
|
|
64
|
-
return this.#promise;
|
|
64
|
+
return this.#defer.promise;
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
setConsentData(data, time = timestamp()) {
|
package/src/debugging.js
CHANGED
|
@@ -4,6 +4,7 @@ import {getGlobal} from './prebidGlobal.js';
|
|
|
4
4
|
import {logMessage, prefixLog} from './utils.js';
|
|
5
5
|
import {createBid} from './bidfactory.js';
|
|
6
6
|
import {loadExternalScript} from './adloader.js';
|
|
7
|
+
import {GreedyPromise} from './utils/promise.js';
|
|
7
8
|
|
|
8
9
|
export const DEBUG_KEY = '__$$PREBID_GLOBAL$$_debugging__';
|
|
9
10
|
|
|
@@ -12,7 +13,7 @@ function isDebuggingInstalled() {
|
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
function loadScript(url) {
|
|
15
|
-
return new
|
|
16
|
+
return new GreedyPromise((resolve) => {
|
|
16
17
|
loadExternalScript(url, 'debugging', resolve);
|
|
17
18
|
});
|
|
18
19
|
}
|
|
@@ -21,7 +22,8 @@ export function debuggingModuleLoader({alreadyInstalled = isDebuggingInstalled,
|
|
|
21
22
|
let loading = null;
|
|
22
23
|
return function () {
|
|
23
24
|
if (loading == null) {
|
|
24
|
-
loading = new
|
|
25
|
+
loading = new GreedyPromise((resolve, reject) => {
|
|
26
|
+
// run this in a 0-delay timeout to give installedModules time to be populated
|
|
25
27
|
setTimeout(() => {
|
|
26
28
|
if (alreadyInstalled()) {
|
|
27
29
|
resolve();
|
|
@@ -44,7 +46,7 @@ export function debuggingControls({load = debuggingModuleLoader(), hook = getHoo
|
|
|
44
46
|
let promise = null;
|
|
45
47
|
let enabled = false;
|
|
46
48
|
function waitForDebugging(next, ...args) {
|
|
47
|
-
return (promise ||
|
|
49
|
+
return (promise || GreedyPromise.resolve()).then(() => next.apply(this, args))
|
|
48
50
|
}
|
|
49
51
|
function enable() {
|
|
50
52
|
if (!enabled) {
|
package/src/hook.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import funHooks from 'fun-hooks/no-eval/index.js';
|
|
2
|
-
import {
|
|
2
|
+
import {defer} from './utils/promise.js';
|
|
3
3
|
|
|
4
4
|
export let hook = funHooks({
|
|
5
5
|
ready: funHooks.SYNC | funHooks.ASYNC | funHooks.QUEUE
|
|
6
6
|
});
|
|
7
7
|
|
|
8
|
-
const readyCtl =
|
|
8
|
+
const readyCtl = defer();
|
|
9
9
|
hook.ready = (() => {
|
|
10
10
|
const ready = hook.ready;
|
|
11
11
|
return function () {
|
package/src/storageManager.js
CHANGED
|
@@ -48,7 +48,7 @@ export function newStorageManager({gvlid, moduleName, bidderCode, moduleType} =
|
|
|
48
48
|
let hookDetails = {
|
|
49
49
|
hasEnforcementHook: false
|
|
50
50
|
}
|
|
51
|
-
validateStorageEnforcement(gvlid, bidderCode || moduleName,
|
|
51
|
+
validateStorageEnforcement(gvlid, bidderCode || moduleName, hookDetails, function(result) {
|
|
52
52
|
if (result && result.hasEnforcementHook) {
|
|
53
53
|
value = cb(result);
|
|
54
54
|
} else {
|
|
@@ -303,7 +303,7 @@ export function newStorageManager({gvlid, moduleName, bidderCode, moduleType} =
|
|
|
303
303
|
/**
|
|
304
304
|
* This hook validates the storage enforcement if gdprEnforcement module is included
|
|
305
305
|
*/
|
|
306
|
-
export const validateStorageEnforcement = hook('async', function(gvlid, moduleName,
|
|
306
|
+
export const validateStorageEnforcement = hook('async', function(gvlid, moduleName, hookDetails, callback) {
|
|
307
307
|
callback(hookDetails);
|
|
308
308
|
}, 'validateStorageEnforcement');
|
|
309
309
|
|
|
@@ -322,13 +322,12 @@ export function getCoreStorageManager(moduleName) {
|
|
|
322
322
|
* @param {Number=} gvlid? Vendor id - required for proper GDPR integration
|
|
323
323
|
* @param {string=} bidderCode? - required for bid adapters
|
|
324
324
|
* @param {string=} moduleName? module name
|
|
325
|
-
* @param {string=} moduleType? module type
|
|
326
325
|
*/
|
|
327
|
-
export function getStorageManager({gvlid, moduleName, bidderCode
|
|
326
|
+
export function getStorageManager({gvlid, moduleName, bidderCode} = {}) {
|
|
328
327
|
if (arguments.length > 1 || (arguments.length > 0 && !isPlainObject(arguments[0]))) {
|
|
329
328
|
throw new Error('Invalid invocation for getStorageManager')
|
|
330
329
|
}
|
|
331
|
-
return newStorageManager({gvlid, moduleName, bidderCode
|
|
330
|
+
return newStorageManager({gvlid, moduleName, bidderCode});
|
|
332
331
|
}
|
|
333
332
|
|
|
334
333
|
export function resetData() {
|
package/src/utils/promise.js
CHANGED
|
@@ -1,36 +1,111 @@
|
|
|
1
1
|
const SUCCESS = 0;
|
|
2
2
|
const FAIL = 1;
|
|
3
|
-
const RESULT = 2;
|
|
4
3
|
|
|
5
4
|
/**
|
|
6
|
-
*
|
|
5
|
+
* A version of Promise that runs callbacks synchronously when it can (i.e. after it's been fulfilled or rejected).
|
|
7
6
|
*/
|
|
8
|
-
export
|
|
9
|
-
|
|
7
|
+
export class GreedyPromise extends Promise {
|
|
8
|
+
#result;
|
|
9
|
+
#callbacks;
|
|
10
|
+
#parent = null;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Convenience wrapper for setTimeout; takes care of returning an already fulfilled GreedyPromise when the delay is zero.
|
|
14
|
+
*
|
|
15
|
+
* @param {Number} delayMs delay in milliseconds
|
|
16
|
+
* @returns {GreedyPromise} a promise that resolves (to undefined) in `delayMs` milliseconds
|
|
17
|
+
*/
|
|
18
|
+
static timeout(delayMs = 0) {
|
|
19
|
+
return new GreedyPromise((resolve) => {
|
|
20
|
+
delayMs === 0 ? resolve() : setTimeout(resolve, delayMs);
|
|
21
|
+
});
|
|
22
|
+
}
|
|
10
23
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
24
|
+
constructor(resolver) {
|
|
25
|
+
const result = [];
|
|
26
|
+
const callbacks = [];
|
|
27
|
+
function handler(type, resolveFn) {
|
|
28
|
+
return function (value) {
|
|
29
|
+
if (!result.length) {
|
|
30
|
+
result.push(type, value);
|
|
31
|
+
while (callbacks.length) callbacks.shift()();
|
|
32
|
+
resolveFn(value);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
super(
|
|
37
|
+
typeof resolver !== 'function'
|
|
38
|
+
? resolver // let super throw an error
|
|
39
|
+
: (resolve, reject) => {
|
|
40
|
+
const rejectHandler = handler(FAIL, reject);
|
|
41
|
+
const resolveHandler = (() => {
|
|
42
|
+
const done = handler(SUCCESS, resolve);
|
|
43
|
+
return value =>
|
|
44
|
+
typeof value?.then === 'function' ? value.then(done, rejectHandler) : done(value);
|
|
45
|
+
})();
|
|
46
|
+
try {
|
|
47
|
+
resolver(resolveHandler, rejectHandler);
|
|
48
|
+
} catch (e) {
|
|
49
|
+
rejectHandler(e);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
);
|
|
53
|
+
this.#result = result;
|
|
54
|
+
this.#callbacks = callbacks;
|
|
55
|
+
}
|
|
56
|
+
then(onSuccess, onError) {
|
|
57
|
+
if (typeof onError === 'function') {
|
|
58
|
+
// if an error handler is provided, attach a dummy error handler to super,
|
|
59
|
+
// and do the same for all promises without an error handler that precede this one in a chain.
|
|
60
|
+
// This is to avoid unhandled rejection events / warnings for errors that were, in fact, handled;
|
|
61
|
+
// since we are not using super's callback mechanisms we need to make it aware of this separately.
|
|
62
|
+
let node = this;
|
|
63
|
+
while (node) {
|
|
64
|
+
super.then.call(node, null, () => null);
|
|
65
|
+
const next = node.#parent;
|
|
66
|
+
node.#parent = null; // since we attached a handler already, we are no longer interested in what will happen later in the chain
|
|
67
|
+
node = next;
|
|
18
68
|
}
|
|
19
69
|
}
|
|
70
|
+
const result = this.#result;
|
|
71
|
+
const res = new GreedyPromise((resolve, reject) => {
|
|
72
|
+
const continuation = () => {
|
|
73
|
+
let value = result[1];
|
|
74
|
+
let [handler, resolveFn] = result[0] === SUCCESS ? [onSuccess, resolve] : [onError, reject];
|
|
75
|
+
if (typeof handler === 'function') {
|
|
76
|
+
try {
|
|
77
|
+
value = handler(value);
|
|
78
|
+
} catch (e) {
|
|
79
|
+
reject(e);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
resolveFn = resolve;
|
|
83
|
+
}
|
|
84
|
+
resolveFn(value);
|
|
85
|
+
}
|
|
86
|
+
result.length ? continuation() : this.#callbacks.push(continuation);
|
|
87
|
+
});
|
|
88
|
+
res.#parent = this;
|
|
89
|
+
return res;
|
|
20
90
|
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* @returns a {promise, resolve, reject} trio where `promise` is resolved by calling `resolve` or `reject`.
|
|
95
|
+
*/
|
|
96
|
+
export function defer({promiseFactory = (resolver) => new GreedyPromise(resolver)} = {}) {
|
|
97
|
+
function invoker(delegate) {
|
|
98
|
+
return (val) => delegate(val);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
let resolveFn, rejectFn;
|
|
21
102
|
|
|
22
103
|
return {
|
|
23
104
|
promise: promiseFactory((resolve, reject) => {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
} else if (status[FAIL] != null) {
|
|
27
|
-
reject(status[RESULT]);
|
|
28
|
-
} else {
|
|
29
|
-
status[SUCCESS] = resolve;
|
|
30
|
-
status[FAIL] = reject;
|
|
31
|
-
}
|
|
105
|
+
resolveFn = resolve;
|
|
106
|
+
rejectFn = reject;
|
|
32
107
|
}),
|
|
33
|
-
resolve:
|
|
34
|
-
reject:
|
|
108
|
+
resolve: invoker(resolveFn),
|
|
109
|
+
reject: invoker(rejectFn)
|
|
35
110
|
}
|
|
36
111
|
}
|
package/src/utils.js
CHANGED
|
@@ -2,6 +2,7 @@ import { config } from './config.js';
|
|
|
2
2
|
import clone from 'just-clone';
|
|
3
3
|
import {find, includes} from './polyfill.js';
|
|
4
4
|
import CONSTANTS from './constants.json';
|
|
5
|
+
import {GreedyPromise} from './utils/promise.js';
|
|
5
6
|
export { default as deepAccess } from 'dlv/index.js';
|
|
6
7
|
export { default as deepSetValue } from 'dset';
|
|
7
8
|
|
|
@@ -487,7 +488,7 @@ export function hasOwn(objectToCheck, propertyToCheckFor) {
|
|
|
487
488
|
* @param {HTMLElement} [doc]
|
|
488
489
|
* @param {HTMLElement} [target]
|
|
489
490
|
* @param {Boolean} [asLastChildChild]
|
|
490
|
-
* @return {
|
|
491
|
+
* @return {HTML Element}
|
|
491
492
|
*/
|
|
492
493
|
export function insertElement(elm, doc, target, asLastChildChild) {
|
|
493
494
|
doc = doc || document;
|
|
@@ -517,7 +518,7 @@ export function insertElement(elm, doc, target, asLastChildChild) {
|
|
|
517
518
|
*/
|
|
518
519
|
export function waitForElementToLoad(element, timeout) {
|
|
519
520
|
let timer = null;
|
|
520
|
-
return new
|
|
521
|
+
return new GreedyPromise((resolve) => {
|
|
521
522
|
const onLoad = function() {
|
|
522
523
|
element.removeEventListener('load', onLoad);
|
|
523
524
|
element.removeEventListener('error', onLoad);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {gdprDataHandler} from 'src/adapterManager.js';
|
|
2
|
+
import {GreedyPromise} from '../../src/utils/promise.js';
|
|
2
3
|
|
|
3
4
|
export function mockGdprConsent(sandbox, getConsentData = () => null) {
|
|
4
|
-
sandbox.stub(gdprDataHandler, 'promise').get(() =>
|
|
5
|
+
sandbox.stub(gdprDataHandler, 'promise').get(() => GreedyPromise.resolve(getConsentData()));
|
|
5
6
|
sandbox.stub(gdprDataHandler, 'getConsentData').callsFake(getConsentData)
|
|
6
7
|
}
|
|
@@ -21,7 +21,6 @@ import {auctionManager} from '../../src/auctionManager.js';
|
|
|
21
21
|
import 'modules/debugging/index.js' // some tests look for debugging side effects
|
|
22
22
|
import {AuctionIndex} from '../../src/auctionIndex.js';
|
|
23
23
|
import {expect} from 'chai';
|
|
24
|
-
import {synchronizePromise} from '../helpers/syncPromise.js';
|
|
25
24
|
|
|
26
25
|
var assert = require('assert');
|
|
27
26
|
|
|
@@ -134,7 +133,7 @@ function mockAjaxBuilder() {
|
|
|
134
133
|
}
|
|
135
134
|
|
|
136
135
|
describe('auctionmanager.js', function () {
|
|
137
|
-
let indexAuctions, indexStub
|
|
136
|
+
let indexAuctions, indexStub
|
|
138
137
|
|
|
139
138
|
before(() => {
|
|
140
139
|
// hooks are global and their side effects depend on what has been loaded
|
|
@@ -150,13 +149,10 @@ describe('auctionmanager.js', function () {
|
|
|
150
149
|
indexAuctions = [];
|
|
151
150
|
indexStub = sinon.stub(auctionManager, 'index');
|
|
152
151
|
indexStub.get(() => new AuctionIndex(() => indexAuctions));
|
|
153
|
-
promiseSandbox = sinon.createSandbox();
|
|
154
|
-
synchronizePromise(promiseSandbox);
|
|
155
152
|
});
|
|
156
153
|
|
|
157
154
|
afterEach(() => {
|
|
158
155
|
indexStub.restore();
|
|
159
|
-
promiseSandbox.restore();
|
|
160
156
|
});
|
|
161
157
|
|
|
162
158
|
describe('getKeyValueTargetingPairs', function () {
|
|
@@ -1458,7 +1454,6 @@ describe('auctionmanager.js', function () {
|
|
|
1458
1454
|
}
|
|
1459
1455
|
|
|
1460
1456
|
beforeEach(() => {
|
|
1461
|
-
promiseSandbox.restore();
|
|
1462
1457
|
bids = [
|
|
1463
1458
|
mockBid({bidderCode: BIDDER_CODE1}),
|
|
1464
1459
|
mockBid({bidderCode: BIDDER_CODE})
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {ready, loadSession, getConfig, reset, debuggingModuleLoader, debuggingControls} from '../../src/debugging.js';
|
|
2
2
|
import {getGlobal} from '../../src/prebidGlobal.js';
|
|
3
|
-
import {
|
|
3
|
+
import {defer} from '../../src/utils/promise.js';
|
|
4
4
|
import funHooks from 'fun-hooks/no-eval/index.js';
|
|
5
5
|
|
|
6
6
|
describe('Debugging', () => {
|
|
@@ -67,7 +67,7 @@ describe('Debugging', () => {
|
|
|
67
67
|
let debugging, loader, hook, hookRan;
|
|
68
68
|
|
|
69
69
|
beforeEach(() => {
|
|
70
|
-
loader =
|
|
70
|
+
loader = defer();
|
|
71
71
|
hookRan = false;
|
|
72
72
|
hook = funHooks()('sync', () => { hookRan = true });
|
|
73
73
|
debugging = debuggingControls({load: sinon.stub().returns(loader.promise), hook});
|