Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@schibsted/niche-ads

Package Overview
Dependencies
Maintainers
6
Versions
60
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@schibsted/niche-ads - npm Package Compare versions

Comparing version 2.0.2 to 3.0.0

20

CHANGELOG.md

@@ -0,1 +1,21 @@

## [3.0.0](https://github.schibsted.io/przemyslaw-babiarz/niche-ads/compare/v2.0.2...v3.0.0) (2023-02-28)
### ⚠ BREAKING CHANGES
- remove loggingEnabled option
- chore: fix typos
### Miscellaneous Chores
- update commitlint monorepo to ^17.4.2 ([#94](https://github.schibsted.io/przemyslaw-babiarz/niche-ads/issues/94)) ([fc1b5f0](https://github.schibsted.io/przemyslaw-babiarz/niche-ads/commit/fc1b5f0ebdeca767cf221adec6e58d355869221a))
- update dependency @babel/core to ^7.20.12 ([#93](https://github.schibsted.io/przemyslaw-babiarz/niche-ads/issues/93)) ([e1b1592](https://github.schibsted.io/przemyslaw-babiarz/niche-ads/commit/e1b15922a2bb81eaef91bf233369fd1b7bb1aa5f))
- update dependency husky to ^8.0.3 ([#92](https://github.schibsted.io/przemyslaw-babiarz/niche-ads/issues/92)) ([30e0356](https://github.schibsted.io/przemyslaw-babiarz/niche-ads/commit/30e03564e63bfe25fec85166ab5c46ba1e32a1c4))
- update dependency lint-staged to ^13.1.2 ([#96](https://github.schibsted.io/przemyslaw-babiarz/niche-ads/issues/96)) ([59039d2](https://github.schibsted.io/przemyslaw-babiarz/niche-ads/commit/59039d23f7c2b21b53657efbb28c84bdd6644e05))
- update linters ([#91](https://github.schibsted.io/przemyslaw-babiarz/niche-ads/issues/91)) ([ecc135f](https://github.schibsted.io/przemyslaw-babiarz/niche-ads/commit/ecc135f8c90d7b43fbb7735b4ea6882d018e1d81))
### Code Refactoring
- general refactor of the context ([#99](https://github.schibsted.io/przemyslaw-babiarz/niche-ads/issues/99)) ([7b42457](https://github.schibsted.io/przemyslaw-babiarz/niche-ads/commit/7b42457b901e72a284cdb84486dad3a98822e4f9))
### [2.0.2](https://github.schibsted.io/przemyslaw-babiarz/niche-ads/compare/v2.0.1...v2.0.2) (2023-01-03)

@@ -2,0 +22,0 @@

206

dist/AdContext.js

@@ -53,36 +53,33 @@ "use strict";

} = _ref;
const [placementsConfig, setPlacementsConfig] = (0, _react.useState)([]);
const [placements, setPlacements] = (0, _react.useState)({});
const [adScriptsReady, setAdScriptsReady] = (0, _react.useState)(false);
const adScriptsReadyRef = (0, _react.useRef)(false);
const placementsConfigRef = (0, _react.useRef)();
const adScriptsReady = (0, _react.useRef)(false);
const placements = (0, _react.useRef)({});
const placementsConfig = (0, _react.useRef)([]);
const placementsMediation = (0, _react.useRef)({});
const retryLoadAds = (0, _react.useRef)(false);
const scriptsLoadPromise = (0, _react.useRef)();
const logger = (0, _react.useCallback)(error => {
if (adsConfig.loggingEnabled) {
console.log(error);
}
}, [adsConfig.loggingEnabled]);
const hasClearPlacementsBeenCalledLast = (0, _react.useRef)(false);
const adsEventTarget = (0, _react.useRef)(new EventTarget());
const sendEvent = (0, _react.useCallback)((targetId, placement, placementConfig) => {
adsEventTarget.current.dispatchEvent(new CustomEvent(targetId, {
detail: {
placement,
placementConfig
}
}));
}, []);
(0, _react.useEffect)(() => {
adScriptsReadyRef.current = adScriptsReady;
}, [adScriptsReady]);
(0, _react.useEffect)(() => {
placementsConfigRef.current = placementsConfig;
}, [placementsConfig]);
const adReadyObserver = (0, _useEvent.default)(ready => {
setAdScriptsReady(ready);
});
(0, _react.useEffect)(() => {
scriptsLoadPromise.current = Promise.all([(0, _loadScript.default)(cdn, 'adsScript'), (0, _loadScript.default)(cogwheelCdn, 'cogwheelScript')]).then(() => {
if (!(0, _appnexus.isASTLoaded)()) {
(0, _appnexus.setUpAPNObject)();
}
(0, _appnexus.subscribeToASTLoad)(adReadyObserver);
resolveAdBlockerDetectedPromise(false);
}).catch(() => {
resolveAdBlockerDetectedPromise(true);
return null;
// resends data to newly attached palacements that use usePlacement
adsEventTarget.current.addEventListener('resend', e => {
const targetId = e.detail;
sendEvent(targetId, placements.current[targetId] ?? hasClearPlacementsBeenCalledLast.current ? null : undefined, placementsConfig.current.find(p => p.targetId === targetId));
});
}, [cdn, cogwheelCdn, adReadyObserver]);
// broadcast data to all listeners in case they attached before this useEffect ran
placementsConfig.current.forEach(placementConfig => {
const targetId = placementConfig.targetId;
sendEvent(targetId, placements.current[targetId] ?? hasClearPlacementsBeenCalledLast.current ? null : undefined, placementsConfig.current.find(p => p.targetId === targetId));
});
}, [sendEvent]);
// handles messages sent by ads library on window object
const messageHandler = (0, _useEvent.default)(async event => {

@@ -95,2 +92,4 @@ if (wallpaper.enabled) {

});
// attaches listener for ads messages on window object
(0, _react.useEffect)(() => {

@@ -109,4 +108,5 @@ window.addEventListener('message', messageHandler);

} = _ref2;
hasClearPlacementsBeenCalledLast.current = false;
await scriptsLoadPromise.current;
if (!device || !adScriptsReadyRef.current) {
if (!device || !adScriptsReady.current) {
retryLoadAds.current = {

@@ -121,3 +121,9 @@ pageType,

retryLoadAds.current = false;
setPlacements({});
// clear current ads
placements.current = {};
placementsConfig.current.forEach(placementConfig => {
sendEvent(placementConfig.targetId, undefined); // undefined to mark ads as not loaded yet
});
placementsMediation.current = {};

@@ -157,14 +163,15 @@ (0, _appnexus.clearRequest)();

}
setPlacementsConfig(newPlacementConfig);
});
(0, _react.useEffect)(() => {
if (retryLoadAds.current) {
const params = retryLoadAds.current;
retryLoadAds.current = false;
loadAds(params);
}
}, [device, loadAds, adScriptsReady]);
(0, _react.useEffect)(() => {
if (placementsConfig?.length > 0) {
const placementsConfigsChunks = (0, _splitEvery.default)(APPNEXUS_PLACEMENTS_PER_REQUEST_LIMIT, placementsConfig);
placementsConfig.current.forEach(placementConfig => {
cleanUpPlacement(placementConfig.targetId);
});
placementsConfig.current = newPlacementConfig;
if (placementsConfig.current?.length > 0) {
const placementsConfigsChunks = (0, _splitEvery.default)(APPNEXUS_PLACEMENTS_PER_REQUEST_LIMIT, placementsConfig.current);
const setPlacement = (placement, placementConfig) => {
placements.current = {
...placements.current,
[placementConfig.targetId]: placement
};
sendEvent(placementConfig.targetId, placement, placementConfig);
};
placementsConfigsChunks.forEach(placementsConfigChunk => {

@@ -181,61 +188,25 @@ placementsConfigChunk.forEach(placementConfig => {

if (placementsMediation.current[placementConfig.targetId] && data.source !== 'csm') {
setPlacements(state => ({
...state,
[placementConfig.targetId]: data
}));
setPlacement(data, placementConfig);
}
});
(0, _appnexus.onEvent)(_appnexus.APPNEXUS_EVENT_TYPES.adAvailable, placementConfig.targetId, data => {
setPlacements(state => ({
...state,
[placementConfig.targetId]: data
}));
setPlacement(data, placementConfig);
});
(0, _appnexus.onEvent)(_appnexus.APPNEXUS_EVENT_TYPES.adBadRequest, placementConfig.targetId, error => {
logger({
error,
placementConfig
});
setPlacements(state => ({
...state,
[placementConfig.targetId]: null
}));
(0, _appnexus.onEvent)(_appnexus.APPNEXUS_EVENT_TYPES.adBadRequest, placementConfig.targetId, () => {
setPlacement(null, placementConfig);
});
(0, _appnexus.onEvent)(_appnexus.APPNEXUS_EVENT_TYPES.adError, placementConfig.targetId, error => {
logger({
error,
placementConfig
});
setPlacements(state => ({
...state,
[placementConfig.targetId]: null
}));
(0, _appnexus.onEvent)(_appnexus.APPNEXUS_EVENT_TYPES.adError, placementConfig.targetId, () => {
setPlacement(null, placementConfig);
});
(0, _appnexus.onEvent)(_appnexus.APPNEXUS_EVENT_TYPES.adCollapse, placementConfig.targetId, () => {
setPlacements(state => ({
...state,
[placementConfig.targetId]: null
}));
setPlacement(null, placementConfig);
});
(0, _appnexus.onEvent)(_appnexus.APPNEXUS_EVENT_TYPES.adNoBid, placementConfig.targetId, () => {
setPlacements(state => ({
...state,
[placementConfig.targetId]: null
}));
setPlacement(null, placementConfig);
});
(0, _appnexus.onEvent)(_appnexus.APPNEXUS_EVENT_TYPES.adRequestFailure, placementConfig.targetId, error => {
logger({
error,
placementConfig
});
setPlacements(state => ({
...state,
[placementConfig.targetId]: null
}));
(0, _appnexus.onEvent)(_appnexus.APPNEXUS_EVENT_TYPES.adRequestFailure, placementConfig.targetId, () => {
setPlacement(null, placementConfig);
});
(0, _appnexus.onEvent)(_appnexus.APPNEXUS_EVENT_TYPES.adRequested, placementConfig.targetId, () => {
setPlacements(state => ({
...state,
[placementConfig.targetId]: undefined
}));
setPlacement(undefined, placementConfig);
});

@@ -245,25 +216,47 @@ });

});
return () => {
placementsConfig.forEach(placementConfig => {
cleanUpPlacement(placementConfig.targetId);
});
};
}
return noop;
}, [placementsConfig, adsConfig?.placements?.common]);
});
const handleLoadAdsReload = (0, _useEvent.default)(() => {
if (retryLoadAds.current) {
const params = retryLoadAds.current;
retryLoadAds.current = false;
loadAds(params);
}
});
// handles edge case when devie changes from undefined to something useful
(0, _react.useEffect)(() => {
handleLoadAdsReload();
}, [device, handleLoadAdsReload]);
const clearPlacements = (0, _useEvent.default)(() => {
placementsConfigRef.current?.forEach(placementConfig => {
cleanUpPlacement(placementConfig.targetId);
hasClearPlacementsBeenCalledLast.current = true;
placementsConfig.current.forEach(placementConfig => {
sendEvent(placementConfig.targetId, null); // null to collapse all placements
});
setPlacements({});
setPlacementsConfig([]);
placements.current = {};
placementsConfig.current = [];
placementsMediation.current = {};
});
(0, _react.useEffect)(() => {
scriptsLoadPromise.current = Promise.all([(0, _loadScript.default)(cdn, 'adsScript'), (0, _loadScript.default)(cogwheelCdn, 'cogwheelScript')]).then(() => {
if (!(0, _appnexus.isASTLoaded)()) {
(0, _appnexus.setUpAPNObject)();
}
(0, _appnexus.subscribeToASTLoad)(ready => {
adScriptsReady.current = ready;
handleLoadAdsReload();
});
resolveAdBlockerDetectedPromise(false);
}).catch(() => {
resolveAdBlockerDetectedPromise(true);
return null;
});
}, [cdn, cogwheelCdn, handleLoadAdsReload]);
const value = (0, _react.useMemo)(() => ({
loadAds,
clearPlacements,
placementsConfig,
placements,
logger,
adBlockerDetectedPromise
}), [placementsConfig, loadAds, placements, clearPlacements, logger]);
adBlockerDetectedPromise,
adsEventTarget: adsEventTarget.current
}), [loadAds, clearPlacements]);
return /*#__PURE__*/(0, _jsxRuntime.jsx)(AdContext.Provider, {

@@ -294,3 +287,2 @@ value: value,

}).isRequired,
loggingEnabled: _propTypes.default.bool,
keywords: _propTypes.default.shape({

@@ -297,0 +289,0 @@ common: _propTypes.default.shape({

@@ -14,7 +14,24 @@ "use strict";

const {
placementsConfig,
placements
adsEventTarget
} = (0, _react.useContext)(_AdContext.default);
const placementConfig = placementsConfig.find(p => p.targetId === targetId);
const placement = placements[targetId];
const [placement, setPlacement] = (0, _react.useState)();
const [placementConfig, setPlacementConfig] = (0, _react.useState)();
(0, _react.useEffect)(() => {
const listener = e => {
const data = e.detail;
setPlacement(data.placement);
// placementConfig doesn't change so we save some computation not sending it when clearing placements
if (data.placementConfig) {
setPlacementConfig(data.placementConfig);
}
};
adsEventTarget.addEventListener(targetId, listener);
adsEventTarget.dispatchEvent(new CustomEvent('resend', {
detail: targetId
}));
return () => {
adsEventTarget.removeEventListener(targetId, listener);
};
}, [adsEventTarget, targetId]);
const showAd = (0, _useEvent.default)(() => {

@@ -25,5 +42,5 @@ if (placement?.targetId) {

});
return (0, _react.useMemo)(() => [placement, showAd, placementConfig], [placement, showAd, placementConfig]);
return (0, _react.useMemo)(() => [placement, showAd, placementConfig], [placement, placementConfig, showAd]);
};
var _default = usePlacement;
exports.default = _default;
{
"name": "@schibsted/niche-ads",
"version": "2.0.2",
"version": "3.0.0",
"description": "Package containing ads logic reappearing across our projects",

@@ -33,21 +33,21 @@ "main": "dist/index.js",

"@babel/cli": "^7.20.7",
"@babel/core": "^7.20.7",
"@babel/core": "^7.20.12",
"@babel/eslint-parser": "^7.19.1",
"@babel/preset-env": "^7.20.2",
"@babel/preset-react": "^7.18.6",
"@commitlint/cli": "^17.3.0",
"@commitlint/config-conventional": "^17.3.0",
"@commitlint/cli": "^17.4.2",
"@commitlint/config-conventional": "^17.4.2",
"@release-it/conventional-changelog": "^5.1.1",
"eslint": "^8.31.0",
"eslint": "^8.33.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-prettier": "^8.5.0",
"eslint-config-prettier": "^8.6.0",
"eslint-plugin-babel": "^5.3.1",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jsx-a11y": "^6.6.1",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-jsx-a11y": "^6.7.1",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-react": "^7.31.11",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
"husky": "^8.0.2",
"lint-staged": "^13.1.0",
"prettier": "^2.8.1",
"husky": "^8.0.3",
"lint-staged": "^13.1.2",
"prettier": "^2.8.3",
"prop-types": "^15.8.1",

@@ -54,0 +54,0 @@ "release-it": "^15.6.0",

@@ -70,3 +70,3 @@ # Niche ads

Ideally you won't ever need to use this directly. It may be usefull for debugging or to peek what the library is storing under the hood. Ideally you should use `AdContextProvider`.
Ideally you won't ever need to use this directly. It may be usefull for debugging or to peek what the library is storing under the hood. Ideally you should use `AdContextProvider`. One thing you may find useful there is `adBlockerDetectedPromise` that is a promise that resolves to a boolean and states whether we suspect that adblock was used (we weren't able to load ad script).

@@ -96,3 +96,2 @@ ### AdContextProvider

- **device** - required - string - one of `desktop`, `tablet`, `mobile`
- **loggingEnabled** - optional - boolean - determines if logging is enabled
- **adsConfig** - required - object - ads configuration object

@@ -122,3 +121,2 @@ - **options** - required - object

},
loggingEnabled: false,
placements: {

@@ -125,0 +123,0 @@ common: {

@@ -1,2 +0,2 @@

import { createContext, useMemo, useState, useRef, useEffect, useCallback } from 'react';
import { createContext, useMemo, useRef, useEffect, useCallback } from 'react';
import PropTypes from 'prop-types';

@@ -52,55 +52,48 @@ import splitEvery from './utils/splitEvery';

function AdContextProvider({ adsConfig, cdn, children, cogwheelCdn, device, wallpaper, glimr }) {
const [placementsConfig, setPlacementsConfig] = useState([]);
const [placements, setPlacements] = useState({});
const [adScriptsReady, setAdScriptsReady] = useState(false);
const adScriptsReadyRef = useRef(false);
const placementsConfigRef = useRef();
const adScriptsReady = useRef(false);
const placements = useRef({});
const placementsConfig = useRef([]);
const placementsMediation = useRef({});
const retryLoadAds = useRef(false);
const scriptsLoadPromise = useRef();
const hasClearPlacementsBeenCalledLast = useRef(false);
const adsEventTarget = useRef(new EventTarget());
const logger = useCallback(
(error) => {
if (adsConfig.loggingEnabled) {
console.log(error);
}
},
[adsConfig.loggingEnabled]
);
const sendEvent = useCallback((targetId, placement, placementConfig) => {
adsEventTarget.current.dispatchEvent(
new CustomEvent(targetId, {
detail: {
placement,
placementConfig,
},
})
);
}, []);
useEffect(() => {
adScriptsReadyRef.current = adScriptsReady;
}, [adScriptsReady]);
// resends data to newly attached palacements that use usePlacement
adsEventTarget.current.addEventListener('resend', (e) => {
const targetId = e.detail;
sendEvent(
targetId,
placements.current[targetId] ?? hasClearPlacementsBeenCalledLast.current ? null : undefined,
placementsConfig.current.find((p) => p.targetId === targetId)
);
});
useEffect(() => {
placementsConfigRef.current = placementsConfig;
}, [placementsConfig]);
// broadcast data to all listeners in case they attached before this useEffect ran
placementsConfig.current.forEach((placementConfig) => {
const targetId = placementConfig.targetId;
sendEvent(
targetId,
placements.current[targetId] ?? hasClearPlacementsBeenCalledLast.current ? null : undefined,
placementsConfig.current.find((p) => p.targetId === targetId)
);
});
}, [sendEvent]);
const adReadyObserver = useEvent((ready) => {
setAdScriptsReady(ready);
});
useEffect(() => {
scriptsLoadPromise.current = Promise.all([
loadScript(cdn, 'adsScript'),
loadScript(cogwheelCdn, 'cogwheelScript'),
])
.then(() => {
if (!isASTLoaded()) {
setUpAPNObject();
}
subscribeToASTLoad(adReadyObserver);
resolveAdBlockerDetectedPromise(false);
})
.catch(() => {
resolveAdBlockerDetectedPromise(true);
return null;
});
}, [cdn, cogwheelCdn, adReadyObserver]);
// handles messages sent by ads library on window object
const messageHandler = useEvent(async (event) => {
if (wallpaper.enabled) {
const attachWallpaperImageToPageBody = await import('./appnexusMessageHandlers/wallpaper');
attachWallpaperImageToPageBody.default(event, wallpaper);

@@ -111,2 +104,3 @@ }

// attaches listener for ads messages on window object
useEffect(() => {

@@ -121,5 +115,6 @@ window.addEventListener('message', messageHandler);

const loadAds = useEvent(async ({ pageType, keywords, allowlist, blocklist }) => {
hasClearPlacementsBeenCalledLast.current = false;
await scriptsLoadPromise.current;
if (!device || !adScriptsReadyRef.current) {
if (!device || !adScriptsReady.current) {
retryLoadAds.current = { pageType, keywords, allowlist, blocklist };

@@ -131,3 +126,8 @@

retryLoadAds.current = false;
setPlacements({});
// clear current ads
placements.current = {};
placementsConfig.current.forEach((placementConfig) => {
sendEvent(placementConfig.targetId, undefined); // undefined to mark ads as not loaded yet
});
placementsMediation.current = {};

@@ -170,17 +170,17 @@ clearRequest();

}
setPlacementsConfig(newPlacementConfig);
});
useEffect(() => {
if (retryLoadAds.current) {
const params = retryLoadAds.current;
retryLoadAds.current = false;
loadAds(params);
}
}, [device, loadAds, adScriptsReady]);
placementsConfig.current.forEach((placementConfig) => {
cleanUpPlacement(placementConfig.targetId);
});
useEffect(() => {
if (placementsConfig?.length > 0) {
const placementsConfigsChunks = splitEvery(APPNEXUS_PLACEMENTS_PER_REQUEST_LIMIT, placementsConfig);
placementsConfig.current = newPlacementConfig;
if (placementsConfig.current?.length > 0) {
const placementsConfigsChunks = splitEvery(APPNEXUS_PLACEMENTS_PER_REQUEST_LIMIT, placementsConfig.current);
const setPlacement = (placement, placementConfig) => {
placements.current = { ...placements.current, [placementConfig.targetId]: placement };
sendEvent(placementConfig.targetId, placement, placementConfig);
};
placementsConfigsChunks.forEach((placementsConfigChunk) => {

@@ -195,28 +195,25 @@ placementsConfigChunk.forEach((placementConfig) => {

if (placementsMediation.current[placementConfig.targetId] && data.source !== 'csm') {
setPlacements((state) => ({ ...state, [placementConfig.targetId]: data }));
setPlacement(data, placementConfig);
}
});
onEvent(APPNEXUS_EVENT_TYPES.adAvailable, placementConfig.targetId, (data) => {
setPlacements((state) => ({ ...state, [placementConfig.targetId]: data }));
setPlacement(data, placementConfig);
});
onEvent(APPNEXUS_EVENT_TYPES.adBadRequest, placementConfig.targetId, (error) => {
logger({ error, placementConfig });
setPlacements((state) => ({ ...state, [placementConfig.targetId]: null }));
onEvent(APPNEXUS_EVENT_TYPES.adBadRequest, placementConfig.targetId, () => {
setPlacement(null, placementConfig);
});
onEvent(APPNEXUS_EVENT_TYPES.adError, placementConfig.targetId, (error) => {
logger({ error, placementConfig });
setPlacements((state) => ({ ...state, [placementConfig.targetId]: null }));
onEvent(APPNEXUS_EVENT_TYPES.adError, placementConfig.targetId, () => {
setPlacement(null, placementConfig);
});
onEvent(APPNEXUS_EVENT_TYPES.adCollapse, placementConfig.targetId, () => {
setPlacements((state) => ({ ...state, [placementConfig.targetId]: null }));
setPlacement(null, placementConfig);
});
onEvent(APPNEXUS_EVENT_TYPES.adNoBid, placementConfig.targetId, () => {
setPlacements((state) => ({ ...state, [placementConfig.targetId]: null }));
setPlacement(null, placementConfig);
});
onEvent(APPNEXUS_EVENT_TYPES.adRequestFailure, placementConfig.targetId, (error) => {
logger({ error, placementConfig });
setPlacements((state) => ({ ...state, [placementConfig.targetId]: null }));
onEvent(APPNEXUS_EVENT_TYPES.adRequestFailure, placementConfig.targetId, () => {
setPlacement(null, placementConfig);
});
onEvent(APPNEXUS_EVENT_TYPES.adRequested, placementConfig.targetId, () => {
setPlacements((state) => ({ ...state, [placementConfig.targetId]: undefined }));
setPlacement(undefined, placementConfig);
});

@@ -226,22 +223,50 @@ });

});
}
});
return () => {
placementsConfig.forEach((placementConfig) => {
cleanUpPlacement(placementConfig.targetId);
});
};
const handleLoadAdsReload = useEvent(() => {
if (retryLoadAds.current) {
const params = retryLoadAds.current;
retryLoadAds.current = false;
loadAds(params);
}
});
return noop;
}, [placementsConfig, adsConfig?.placements?.common]);
// handles edge case when devie changes from undefined to something useful
useEffect(() => {
handleLoadAdsReload();
}, [device, handleLoadAdsReload]);
const clearPlacements = useEvent(() => {
placementsConfigRef.current?.forEach((placementConfig) => {
cleanUpPlacement(placementConfig.targetId);
hasClearPlacementsBeenCalledLast.current = true;
placementsConfig.current.forEach((placementConfig) => {
sendEvent(placementConfig.targetId, null); // null to collapse all placements
});
setPlacements({});
setPlacementsConfig([]);
placements.current = {};
placementsConfig.current = [];
placementsMediation.current = {};
});
useEffect(() => {
scriptsLoadPromise.current = Promise.all([
loadScript(cdn, 'adsScript'),
loadScript(cogwheelCdn, 'cogwheelScript'),
])
.then(() => {
if (!isASTLoaded()) {
setUpAPNObject();
}
subscribeToASTLoad((ready) => {
adScriptsReady.current = ready;
handleLoadAdsReload();
});
resolveAdBlockerDetectedPromise(false);
})
.catch(() => {
resolveAdBlockerDetectedPromise(true);
return null;
});
}, [cdn, cogwheelCdn, handleLoadAdsReload]);
const value = useMemo(

@@ -251,8 +276,6 @@ () => ({

clearPlacements,
placementsConfig,
placements,
logger,
adBlockerDetectedPromise,
adsEventTarget: adsEventTarget.current,
}),
[placementsConfig, loadAds, placements, clearPlacements, logger]
[loadAds, clearPlacements]
);

@@ -285,3 +308,2 @@

}).isRequired,
loggingEnabled: PropTypes.bool,
keywords: PropTypes.shape({

@@ -288,0 +310,0 @@ common: PropTypes.shape({

@@ -1,2 +0,2 @@

import { useContext, useMemo } from 'react';
import { useContext, useEffect, useMemo, useState } from 'react';
import { showTag } from './utils/appnexus';

@@ -7,6 +7,25 @@ import AdContext from './AdContext';

const usePlacement = (targetId) => {
const { placementsConfig, placements } = useContext(AdContext);
const placementConfig = placementsConfig.find((p) => p.targetId === targetId);
const placement = placements[targetId];
const { adsEventTarget } = useContext(AdContext);
const [placement, setPlacement] = useState();
const [placementConfig, setPlacementConfig] = useState();
useEffect(() => {
const listener = (e) => {
const data = e.detail;
setPlacement(data.placement);
// placementConfig doesn't change so we save some computation not sending it when clearing placements
if (data.placementConfig) {
setPlacementConfig(data.placementConfig);
}
};
adsEventTarget.addEventListener(targetId, listener);
adsEventTarget.dispatchEvent(new CustomEvent('resend', { detail: targetId }));
return () => {
adsEventTarget.removeEventListener(targetId, listener);
};
}, [adsEventTarget, targetId]);
const showAd = useEvent(() => {

@@ -18,5 +37,5 @@ if (placement?.targetId) {

return useMemo(() => [placement, showAd, placementConfig], [placement, showAd, placementConfig]);
return useMemo(() => [placement, showAd, placementConfig], [placement, placementConfig, showAd]);
};
export default usePlacement;
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc