summaryrefslogtreecommitdiff
path: root/node_modules/@jet-app/app-store/tmp/src/common/search/search-landing-page-utils.js
blob: f26b78b7d526c090f4ce61081fd39f35e09f283a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
import * as validation from "@jet/environment/json/validation";
import { FetchTimingMetricsBuilder } from "@jet/environment/metrics/fetch-timing-metrics-builder";
import { isNothing, isSome } from "@jet/environment/types/optional";
import { PageRefreshPolicy, SearchAction, SearchFocusPage, SearchLandingPage, Shelf } from "../../api/models";
import * as mediaRequestUtils from "../../common/builders/url-mapping-utils";
import * as appStoreExperiments from "../../foundation/experimentation/app-store-experiments";
import { ExperimentAreaId } from "../../foundation/experimentation/experiment-area-id";
import * as serverData from "../../foundation/json-parsing/server-data";
import * as mediaAttributes from "../../foundation/media/attributes";
import * as mediaDataFetching from "../../foundation/media/data-fetching";
import * as mediaNetwork from "../../foundation/media/network";
import * as mediaRelationship from "../../foundation/media/relationships";
import { Parameters, Path, Protocol } from "../../foundation/network/url-constants";
import * as impressionDemotion from "../../common/personalization/on-device-impression-demotion";
import { iadInfoFromOnDeviceAdResponse, isAdPlacementEnabled } from "../ads/ad-common";
import * as adIncidents from "../ads/ad-incident-recorder";
import { fetchAds as landingAdFetchFetchAds } from "../ads/on-device-ad-fetch";
import * as landingAdStitch from "../ads/on-device-ad-stitch";
import * as contentArtwork from "../content/artwork/artwork";
import * as groupingCommon from "../grouping/grouping-common";
import * as metricsHelpersClicks from "../metrics/helpers/clicks";
import * as metricsHelpersLocation from "../metrics/helpers/location";
import * as metricsHelpersPage from "../metrics/helpers/page";
import * as metricsHelpersUtil from "../metrics/helpers/util";
import * as onDevicePersonalization from "../personalization/on-device-personalization";
import * as productPageVariants from "../product-page/product-page-variants";
import { areAppTagsEnabled } from "../util/app-tags-util";
import { isFeatureEnabledForCurrentUser } from "../util/lottery";
import { SearchPageType } from "./content/search-shelves";
import * as searchLandingCohort from "./landing/search-landing-cohort";
import * as searchLandingShelfController from "./landing/search-landing-shelf-controller";
/**
 * Determines whether or not the user will use the legacy Search Landing Page protocol
 * @param objectGraph The App Store Object Graph
 * @returns Whether or not the user will use the legacy Search Landing Page protocol
 */
function shouldUseProtocolV1(objectGraph) {
    if (objectGraph.client.isVision) {
        return false; // visionOS always uses the modern V2 protocol.
    }
    if (objectGraph.client.isWeb) {
        return false; // the "web" expects to use the V2 protocol as well
    }
    if (!objectGraph.bag.supportsSearchLandingPageV2) {
        return true; // Use V1 protocol when V2 is unsupported
    }
    // Use V1 protocol based on the bags rollout rate for V2 protocol.
    return !isFeatureEnabledForCurrentUser(objectGraph, objectGraph.bag.searchLandingPageV2RolloutRate);
}
async function fetchSearchLandingPage(objectGraph, fetchAds) {
    if (shouldUseProtocolV1(objectGraph)) {
        return await fetchSearchLandingPageV1(objectGraph, fetchAds);
    }
    if (objectGraph.bag.mediaAPISearchFocusEnabled) {
        return await fetchSearchLandingPageV2WithFocusPage(objectGraph, fetchAds);
    }
    return await fetchSearchLandingPageV2(objectGraph, fetchAds);
}
async function fetchSearchLandingPageV1(objectGraph, fetchAds) {
    const searchLandingRequest = new mediaDataFetching.Request(objectGraph)
        .forType("landing")
        .includingAgeRestrictions()
        .includingAdditionalPlatforms(mediaDataFetching.defaultAdditionalPlatformsForClient(objectGraph))
        .usingCustomAttributes(productPageVariants.shouldFetchCustomAttributes(objectGraph)); // for `extend=customArtwork`
    searchLandingRequest.targetResourceType = "groupings";
    const cohortIdOrNil = searchLandingCohort.cohortIdForUser(objectGraph, objectGraph.user.dsid);
    if ((cohortIdOrNil === null || cohortIdOrNil === void 0 ? void 0 : cohortIdOrNil.length) > 0) {
        searchLandingRequest.addingQuery("clusterId", cohortIdOrNil);
    }
    const fetchTimingMetricsBuilder = new FetchTimingMetricsBuilder();
    const modifiedObjectGraph = objectGraph.addingFetchTimingMetricsBuilder(fetchTimingMetricsBuilder);
    const fetchSearchLanding = mediaNetwork.fetchData(modifiedObjectGraph, searchLandingRequest);
    return await Promise.all([fetchSearchLanding, fetchAds]).then(([responseData, adResponse]) => {
        return fetchTimingMetricsBuilder.measureModelConstruction(() => {
            return landingPageFromResponseV1(modifiedObjectGraph, responseData, adResponse);
        });
    });
}
/**
 * Creates `SearchLandingPage` model from the V1 Search Landing Page protocol
 * @param objectGraph The App Store Object Graph
 * @param landingPageResponse The response from the fetch
 * @param adResponse The response from the ad fetch
 * @returns A `SearchLandingPage` model from the V1 Search Landing Page protocol
 */
function landingPageFromResponseV1(objectGraph, landingPageResponse, adResponse) {
    const mediaApiGroupingDataArray = serverData.asArrayOrEmpty(landingPageResponse, "results.contents");
    const mediaApiGroupingData = mediaApiGroupingDataArray[0];
    if (serverData.isNullOrEmpty(mediaApiGroupingData)) {
        return null;
    }
    if (!mediaRelationship.hasRelationship(mediaApiGroupingData, "tabs")) {
        return null;
    }
    const groupingGenreAdamId = mediaAttributes.attributeAsString(mediaApiGroupingData, "id");
    const pageInformation = metricsHelpersPage.metricsPageInformationFromMediaApiResponse(objectGraph, "Genre", mediaApiGroupingData.id, landingPageResponse);
    const onDevicePersonalizationMetricsData = onDevicePersonalization.metricsData(objectGraph);
    pageInformation.recoMetricsData = metricsHelpersUtil.combinedRecoMetricsDataFromMetricsData(pageInformation.recoMetricsData, null, onDevicePersonalizationMetricsData);
    pageInformation.iAdInfo = iadInfoFromOnDeviceAdResponse(objectGraph, "searchLanding", adResponse);
    const adIncidentRecorder = adIncidents.newRecorder(objectGraph, pageInformation.iAdInfo);
    adIncidents.recordAdResponseEventsIfNeeded(objectGraph, adIncidentRecorder, adResponse);
    const groupingParseContext = {
        shelves: [],
        metricsPageInformation: pageInformation,
        metricsLocationTracker: metricsHelpersLocation.newLocationTracker(),
        pageGenreAdamId: groupingGenreAdamId,
        pageGenreId: mediaAttributes.attributeAsNumber(mediaApiGroupingData, "genre"),
        hasAuthenticatedUser: serverData.isDefinedNonNull(objectGraph.user.dsid),
        isSearchLandingPage: true,
        adStitcher: landingAdStitch.adStitcherForOnDeviceSLPAdvertData(objectGraph, adResponse),
        adIncidentRecorder: adIncidentRecorder,
    };
    const flattenedGrouping = groupingCommon.flattenMediaApiGroupingData(objectGraph, mediaApiGroupingData);
    groupingCommon.insertInitialShelvesIntoGroupingParseContext(objectGraph, flattenedGrouping, groupingParseContext);
    const page = new SearchLandingPage(groupingParseContext.shelves);
    // Page refresh
    const refreshPolicy = new PageRefreshPolicy("timeSinceOnScreen", objectGraph.bag.searchLandingPageRefreshUpdateDelayInterval, objectGraph.bag.searchLandingPageOffscreenRefreshInterval, null);
    page.pageRefreshPolicy = refreshPolicy;
    // Ad Incidents
    page.adIncidents = adIncidents.recordedIncidents(objectGraph, groupingParseContext.adIncidentRecorder);
    metricsHelpersPage.addMetricsEventsToPageWithInformation(objectGraph, page, groupingParseContext.metricsPageInformation);
    return page;
}
function makeSearchLandingRequestV2(objectGraph, fetchAds) {
    const searchLandingRequest = new mediaDataFetching.Request(objectGraph)
        .forType("landing:new-protocol")
        .includingAgeRestrictions()
        .includingAdditionalPlatforms(mediaDataFetching.defaultAdditionalPlatformsForClient(objectGraph))
        .usingCustomAttributes(productPageVariants.shouldFetchCustomAttributes(objectGraph)) // for `extend=customArtwork`
        .includingScopedRelationships("search-recommendations", ["contents"])
        .addingQuery("name", "search-landing");
    if (areAppTagsEnabled(objectGraph, "slp")) {
        mediaRequestUtils.configureTagsForMediaRequest(searchLandingRequest);
    }
    if (objectGraph.client.isVision || objectGraph.client.isWeb) {
        searchLandingRequest.includingScopedAttributes("editorial-items", ["editorialClientParams"]);
    }
    const cohortIdOrNil = searchLandingCohort.cohortIdForUser(objectGraph, objectGraph.user.dsid);
    if ((cohortIdOrNil === null || cohortIdOrNil === void 0 ? void 0 : cohortIdOrNil.length) > 0) {
        searchLandingRequest.addingQuery("clusterId", cohortIdOrNil);
    }
    if (objectGraph.client.isiOS) {
        searchLandingRequest.addingQuery("meta", "adDisplayStyle");
    }
    return searchLandingRequest;
}
async function fetchSearchLandingPageV2(objectGraph, fetchAds) {
    const searchLandingRequest = makeSearchLandingRequestV2(objectGraph, fetchAds);
    const fetchTimingMetricsBuilder = new FetchTimingMetricsBuilder();
    const modifiedObjectGraph = objectGraph.addingFetchTimingMetricsBuilder(fetchTimingMetricsBuilder);
    const fetchSearchLanding = mediaNetwork.fetchData(modifiedObjectGraph, searchLandingRequest);
    const amsEngagement = objectGraph.amsEngagement;
    let amdPromise;
    if (amsEngagement && objectGraph.bag.enableRecoOnDeviceReordering) {
        const request = {
            timeout: 500,
            eventType: impressionDemotion.AMSEngagementAppStoreEventKey,
            tab: "search",
        };
        amdPromise = amsEngagement.performRequest(request);
    }
    return await Promise.all([fetchSearchLanding, fetchAds, amdPromise]).then(([responseData, adResponse, amdResponse]) => {
        return fetchTimingMetricsBuilder.measureModelConstruction(() => {
            return landingPageFromResponseV2(modifiedObjectGraph, responseData, adResponse, amdResponse);
        });
    });
}
/**
 * Creates `SearchLandingPage` model from the V2 Search Landing Page protocol
 * @param objectGraph The App Store Object Graph
 * @param landingPageResponse The response from the fetch
 * @param adResponse The response from the ad fetch
 * @returns A `SearchLandingPage` model from the V2 Search Landing Page protocol
 */
function landingPageFromResponseV2(objectGraph, landingPageResponse, adResponse, impressionData) {
    if (serverData.isNullOrEmpty(landingPageResponse.data)) {
        return null;
    }
    // Creates the page info
    const pageInformation = metricsHelpersPage.metricsPageInformationFromMediaApiResponse(objectGraph, "SearchLanding", "SearchLanding", landingPageResponse);
    // Decorate page info with personalization metrics
    const onDevicePersonalizationMetricsData = onDevicePersonalization.metricsData(objectGraph);
    pageInformation.recoMetricsData = metricsHelpersUtil.combinedRecoMetricsDataFromMetricsData(pageInformation.recoMetricsData, null, onDevicePersonalizationMetricsData);
    pageInformation.iAdInfo = iadInfoFromOnDeviceAdResponse(objectGraph, "searchLanding", adResponse);
    const adIncidentRecorder = adIncidents.newRecorder(objectGraph, pageInformation.iAdInfo);
    adIncidents.recordAdResponseEventsIfNeeded(objectGraph, adIncidentRecorder, adResponse);
    // Creates Search Landing Page Context
    const landingPageContext = {
        shelves: [],
        metricsLocationTracker: metricsHelpersLocation.newLocationTracker(),
        metricsPageInformation: pageInformation,
        adStitcher: landingAdStitch.adStitcherForOnDeviceSLPAdvertData(objectGraph, adResponse, landingPageResponse),
        adIncidentRecorder: adIncidentRecorder,
        pageType: SearchPageType.Landing,
        recoImpressionData: impressionDemotion.impressionEventsFromData(objectGraph, impressionData),
    };
    // Create the shelves for the page
    searchLandingShelfController.insertShelvesIntoSearchPageContext(objectGraph, landingPageResponse, landingPageContext);
    // Add Unified Messaging placement to top of page for NLS BT.
    const bubbleTipShelf = createNaturalLanguageSearchBubbleTipShelf(objectGraph);
    if (bubbleTipShelf) {
        landingPageContext.shelves.unshift(bubbleTipShelf);
    }
    const landingPage = new SearchLandingPage(landingPageContext.shelves);
    // Page refresh
    landingPage.pageRefreshPolicy = new PageRefreshPolicy("timeSinceOnScreen", objectGraph.bag.searchLandingPageRefreshUpdateDelayInterval, objectGraph.bag.searchLandingPageOffscreenRefreshInterval, null);
    // Ad Incidents
    landingPage.adIncidents = adIncidents.recordedIncidents(objectGraph, landingPageContext.adIncidentRecorder);
    metricsHelpersPage.addMetricsEventsToPageWithInformation(objectGraph, landingPage, landingPageContext.metricsPageInformation);
    return landingPage;
}
/**
 * Creates the NLS BT shelf for SLP if enabled.
 * @param objectGraph The app store object graph.
 * @returns The shelf for the NLS BT shown on SLP, or undefined if bag has feature disabled.
 */
export function createNaturalLanguageSearchBubbleTipShelf(objectGraph) {
    var _a;
    if (!objectGraph.bag.isNaturalLanguageSearchEnabled && !objectGraph.bag.isNaturalLanguageSearchResultsEnabled) {
        return undefined; // feature not enabled in the bag
    }
    const context = {
        signal: {
            lastNLSQueryDate: objectGraph.storage.retrieveString("lastNLSQueryDate"),
            treatmentId: (_a = appStoreExperiments.currentTreatmentIdForArea(objectGraph, ExperimentAreaId.SearchLandingPage)) !== null && _a !== void 0 ? _a : null,
        },
    };
    const shelf = groupingCommon.shelfForUnifiedMessage(objectGraph, "searchFocusHeader", context, "pullOnly");
    shelf.refreshUrl = `${Protocol.internal}:/${Path.searchLandingPage}/${Path.shelf}/?${Parameters.isSearchFocusHeaderShelf}=true`;
    return shelf;
}
async function fetchSearchLandingPageV2WithFocusPage(objectGraph, fetchAds) {
    const searchLandingRequest = makeSearchLandingRequestV2(objectGraph, fetchAds).enablingFeature("search-focus-suggestions");
    const fetchTimingMetricsBuilder = new FetchTimingMetricsBuilder();
    const modifiedObjectGraph = objectGraph.addingFetchTimingMetricsBuilder(fetchTimingMetricsBuilder);
    const fetchSearchLanding = mediaNetwork.fetchData(modifiedObjectGraph, searchLandingRequest);
    const amsEngagement = objectGraph.amsEngagement;
    let amdPromise = null;
    if (amsEngagement && objectGraph.bag.enableRecoOnDeviceReordering) {
        const request = {
            timeout: 500,
            eventType: impressionDemotion.AMSEngagementAppStoreEventKey,
            tab: "search",
        };
        amdPromise = amsEngagement.performRequest(request);
    }
    return await Promise.all([fetchSearchLanding, fetchAds, amdPromise]).then(async ([responseData, adResponse, amdResponse]) => {
        return await fetchTimingMetricsBuilder.measureModelConstructionAsync(async () => await landingPageFromResponseV2WithFocusPage(modifiedObjectGraph, responseData, adResponse, amdResponse));
    });
}
/**
 * Creates `SearchLandingPage` model from the V2 Search Landing Page protocol, but with search-focus feature enabled.
 * @param objectGraph The App Store Object Graph
 * @param landingPageResponse The response from the landing fetch
 * @param landingAdResponse The response from the landingAd fetch
 * @returns A `SearchLandingPage` model created from server response.
 */
async function landingPageFromResponseV2WithFocusPage(objectGraph, landingPageResponse, landingAdResponse, impressionData) {
    // MAINTAINER'S NOTE: V3 protocol does not change any existing SLP v2 fields and is purely additives for focus page support
    const landingPage = landingPageFromResponseV2(objectGraph, landingPageResponse, landingAdResponse, impressionData);
    // Create Search Focus Page
    return await fetchFocusPageUsingLandingPageResponse(objectGraph, landingPageResponse).then((focusPage) => {
        landingPage.searchFocusPage = focusPage;
        return landingPage;
    });
}
/**
 * Creates `SearchFocusPage` model from the V3 Search Landing Page protocol, fetching search history if needed.
 * @param objectGraph The App Store Object Graph
 * @param focusPageResponse The response from the fetch
 * @returns A `SearchFocusPage` model from the V3 Search Landing Page protocol
 */
async function fetchFocusPageUsingLandingPageResponse(objectGraph, landingPageResponse) {
    var _a;
    if (serverData.isNullOrEmpty(landingPageResponse.data)) {
        return null;
    }
    // Creates the page info
    const pageInformation = metricsHelpersPage.metricsPageInformationFromMediaApiResponse(objectGraph, "SearchFocus", "Focus", landingPageResponse, " ");
    // Decorate page info with personalization metrics
    const onDevicePersonalizationMetricsData = onDevicePersonalization.metricsData(objectGraph);
    pageInformation.recoMetricsData = metricsHelpersUtil.combinedRecoMetricsDataFromMetricsData(pageInformation.recoMetricsData, null, onDevicePersonalizationMetricsData);
    // Creates Search Focus Page Context
    const focusPageContext = {
        shelves: [],
        metricsLocationTracker: metricsHelpersLocation.newLocationTracker(),
        metricsPageInformation: pageInformation,
        pageType: SearchPageType.Focus,
    };
    const searchHistoryShelfMarker = searchLandingShelfController.firstShelfMarkerMatchingUseCase(landingPageResponse, focusPageContext, "recentSearches");
    // Skip fetching search history if there isn't a marker for it in SLP response.
    if (isNothing(searchHistoryShelfMarker)) {
        return createFocusPageFromResponse(objectGraph, landingPageResponse, focusPageContext);
    }
    const searchHistoryDisplayCount = (_a = mediaAttributes.attributeAsNumber(searchHistoryShelfMarker, "displayCount")) !== null && _a !== void 0 ? _a : 0;
    const fetchSearchHistory = objectGraph.onDeviceSearchHistoryManager.fetchRecentsWithLimit(searchHistoryDisplayCount);
    return await fetchSearchHistory.then((searchHistory) => {
        focusPageContext.searchHistory = searchHistory;
        return createFocusPageFromResponse(objectGraph, landingPageResponse, focusPageContext);
    });
}
function createFocusPageFromResponse(objectGraph, landingPageResponse, focusPageContext) {
    // Create the shelves for the focus page using same logic as landing page, but
    // includes search history in page context to support `search-recommendations-marker`.
    searchLandingShelfController.insertShelvesIntoSearchPageContext(objectGraph, landingPageResponse, focusPageContext);
    const focusPage = new SearchFocusPage(focusPageContext.shelves);
    if (serverData.isNullOrEmpty(focusPage.shelves)) {
        return null;
    }
    metricsHelpersPage.addMetricsEventsToPageWithInformation(objectGraph, focusPage, focusPageContext.metricsPageInformation);
    return focusPage;
}
async function fetchTrendingSearchesFallbackPage(objectGraph, fetchAds) {
    const fetchRequest = {
        url: objectGraph.bag.trendingSearchesURL,
    };
    const trendingSearchesPromise = objectGraph.network.fetch(fetchRequest).then((response) => {
        if (!response.ok) {
            throw Error(`Bad Status code ${response.status} for ${fetchRequest.url}`);
        }
        return JSON.parse(response.body);
    });
    return await Promise.all([trendingSearchesPromise, fetchAds]).then(([trendingSearchesData, adResponse]) => {
        var _a;
        const page = new SearchLandingPage(trendingSearchesShelvesForResponse(objectGraph, trendingSearchesData));
        const pageInformation = metricsHelpersPage.fakeMetricsPageInformation(objectGraph, "SearchLanding", "trending", ""); // old trending endpoint doesn't have metrics meta
        pageInformation.iAdInfo = iadInfoFromOnDeviceAdResponse(objectGraph, "searchLanding", adResponse);
        (_a = pageInformation.iAdInfo) === null || _a === void 0 ? void 0 : _a.setMissedOpportunity(objectGraph, "SLPLOAD", "searchLanding"); // trending fallback never displays ad, so is always missed opportunity.
        metricsHelpersPage.addMetricsEventsToPageWithInformation(objectGraph, page, pageInformation);
        return page;
    });
}
/**
 * Creates a trending searches shelves from the given JSON response.
 *  @param  objectGraph  The App Store Object Graph.
 *  @param  response    The API response JSON data.
 *  @return {Shelf[]} Trending searches shelves created from response.
 */
function trendingSearchesShelvesForResponse(objectGraph, response) {
    return validation.context("trendingSearchesShelfForResponse", () => {
        const locationTracker = metricsHelpersLocation.newLocationTracker();
        const searches = serverData.asArrayOrEmpty(response, "trendingSearches").map((rawSearch) => {
            const term = serverData.asString(rawSearch, "label");
            const searchAction = new SearchAction(term, term, serverData.asString(rawSearch, "url"), "trending");
            if (objectGraph.client.isPhone) {
                searchAction.artwork = contentArtwork.createArtworkForResource(objectGraph, "systemimage://magnifyingglass");
            }
            metricsHelpersClicks.addEventsToSearchAction(objectGraph, searchAction, "button", locationTracker);
            metricsHelpersLocation.nextPosition(locationTracker);
            return searchAction;
        });
        let maxNumberOfSearches = 0;
        switch (objectGraph.client.deviceType) {
            case "pad":
                maxNumberOfSearches = 10;
                break;
            case "phone":
                maxNumberOfSearches = 7;
                break;
            default:
                break;
        }
        const shelf = new Shelf("action");
        shelf.title = searches.length > 0 ? serverData.asString(response, "header.label") : null;
        shelf.isHorizontal = false;
        shelf.items = searches.slice(0, maxNumberOfSearches);
        return [shelf];
    });
}
export async function fetchPage(objectGraph) {
    const fetchAds = isAdPlacementEnabled(objectGraph, "searchLanding")
        ? landingAdFetchFetchAds(objectGraph, "searchLanding").catch(() => null)
        : null;
    return await fetchSearchLandingPage(objectGraph, fetchAds).catch(async (e) => {
        // If the client has provided a `trendingSearchesURL`, we can fallback to that search
        // mechanism if the search landing request fails. If `trendingSearchesURL` is not
        // provided, we re-throw the original landing page error for the client to handle.
        if (isSome(objectGraph.bag.trendingSearchesURL)) {
            return await fetchTrendingSearchesFallbackPage(objectGraph, fetchAds);
        }
        else {
            throw e;
        }
    });
}
//# sourceMappingURL=search-landing-page-utils.js.map