/** * Implements the ODML Treatment (On-device machine learning) for Sponsored search. */ "use strict"; import { adLogger } from "../../common/search/search-ads"; import { isNull, isNullOrEmpty } from "../../foundation/json-parsing/server-data"; import { shallowCopyOf } from "../../foundation/util/objects"; import { decorateAdInstanceIdOnData } from "../ads/ad-common"; import { productVariantDataForData, productVariantIDForVariantData } from "../product-page/product-page-variants"; // region exports /** * Merge the contents of the raw response with the data in `advertData` from `SearchAds.framework` * * @param rawAdverts The adverts returned in the network response. * @param nativeAdvertData The advert data that was returned from native. */ export function applyNativeAdvertData(objectGraph, rawAdverts, nativeAdvertData) { if (isNull(nativeAdvertData)) { return rawAdverts; // even if `nativeAdvertData` may contain error, we need to perform apply to merge instance ids. } const updated = []; const rawAdvertsMap = rawAdverts.reduce((acc, data) => ({ ...acc, [data.id]: data }), {}); for (const nativeAdData of nativeAdvertData.adverts) { const rawAd = rawAdvertsMap[nativeAdData.adamId]; if (isNullOrEmpty(rawAd)) { adLogger(objectGraph, `[${nativeAdData.adamId}] skipped - Data was not part of original response`); continue; } if (isNullOrEmpty(rawAd.attributes)) { adLogger(objectGraph, `[${rawAd.id}] skipped - Data is missing attributes`); continue; } const newAd = createCopyWithNativeData(objectGraph, rawAd, nativeAdData); updated.push(newAd); } if (!preprocessor.PRODUCTION_BUILD) { const rawOrder = rawAdverts.map((ad) => ad.id).join(" "); const updatedOrder = updated.map((ad) => ad.id).join(" "); adLogger(objectGraph, `applyNativeAdvertData: [${rawOrder}] => [${updatedOrder}]`); } return updated; } /** * Returns whether or not ODML treatment was successful */ export function wasODMLSuccessful(objectGraph, nativeAdvertData) { return nativeAdvertData && nativeAdvertData.odmlSuccess; } // endregion // region internals /** * Create a copy of `ad` with the `adData` replacing the "iad" attribute. * @param ad The raw ad to copy * @param adData The ad blob to overrwite wth. */ function createCopyWithNativeData(objectGraph, ad, nativeAdData) { const copy = shallowCopyOf(ad); const attributes = shallowCopyOf(ad.attributes); attributes["iads"] = nativeAdData.adData; copy.attributes = attributes; overrideCustomProductPageIdIfRequired(objectGraph, copy, nativeAdData); decorateAdInstanceIdOnData(objectGraph, copy, nativeAdData.instanceId); return copy; } /** * Modifies an `ad` by overriding the `ppid` value if native ODML has dictated a new selection. * Note: This may intentionally replace the `ppid` value with `null` if CPP is disabled for Search Ads. * If we pass native all `null` values for ODML processing (because the feature is disabled in the bag), * we expect to receive `null` back and insert `null` into the `ad` here. * @param ad The ad to modify. * @param adData The ad blob to overrwite with. */ function overrideCustomProductPageIdIfRequired(objectGraph, ad, nativeAdData) { var _a; const productVariantData = productVariantDataForData(objectGraph, ad); const productVariantId = productVariantIDForVariantData(productVariantData); // If there is a "selected" cppId, and it's different to the `serverCppId`, native has made a new selection. // Confirm we have a cppData of meta to modify if (nativeAdData.selectedCppId === productVariantId || isNullOrEmpty((_a = ad === null || ad === void 0 ? void 0 : ad.meta) === null || _a === void 0 ? void 0 : _a.cppData)) { return; } // Modify the meta data with the new selection. const meta = shallowCopyOf(ad.meta); meta.cppData["ppid"] = nativeAdData.selectedCppId; ad.meta = meta; } //# sourceMappingURL=search-ads-odml.js.map