Merged in fix/warmup-autocomplete-data (pull request #2212)
warmup autocomplete data * warmup autocomplete data Approved-by: Anton Gunnarsson
This commit is contained in:
@@ -40,105 +40,13 @@ type DestinationsAutoCompleteOutput = {
|
||||
export const getDestinationsAutoCompleteRoute = safeProtectedServiceProcedure
|
||||
.input(destinationsAutoCompleteInputSchema)
|
||||
.query(async ({ ctx, input }): Promise<DestinationsAutoCompleteOutput> => {
|
||||
const cacheClient = await getCacheClient()
|
||||
|
||||
const lang = input.lang || ctx.lang
|
||||
|
||||
const locations: AutoCompleteLocation[] = await cacheClient.cacheOrGet(
|
||||
`autocomplete:destinations:locations:${lang}`,
|
||||
async () => {
|
||||
const hotelUrlsPromise = safeTry(getHotelPageUrls(lang))
|
||||
const cityUrlsPromise = safeTry(getCityPageUrls(lang))
|
||||
const countryUrlsPromise = safeTry(getCountryPageUrls(lang))
|
||||
const countries = await getCountries({
|
||||
lang: lang,
|
||||
serviceToken: ctx.serviceToken,
|
||||
})
|
||||
|
||||
if (!countries) {
|
||||
throw new Error("Unable to fetch countries")
|
||||
}
|
||||
|
||||
const countryNames = countries.data.map((country) => country.name)
|
||||
const citiesByCountry = await getCitiesByCountry({
|
||||
countries: countryNames,
|
||||
serviceToken: ctx.serviceToken,
|
||||
lang,
|
||||
})
|
||||
|
||||
const locations = await getLocations({
|
||||
lang: lang,
|
||||
serviceToken: ctx.serviceToken,
|
||||
citiesByCountry: citiesByCountry,
|
||||
})
|
||||
|
||||
const activeLocations = locations.filter((location) => {
|
||||
return (
|
||||
location.type === "cities" ||
|
||||
(location.type === "hotels" && location.isActive)
|
||||
)
|
||||
})
|
||||
|
||||
const [hotelUrls, hotelUrlsError] = await hotelUrlsPromise
|
||||
const [cityUrls, cityUrlsError] = await cityUrlsPromise
|
||||
const [countryUrls, countryUrlsError] = await countryUrlsPromise
|
||||
|
||||
if (
|
||||
hotelUrlsError ||
|
||||
cityUrlsError ||
|
||||
countryUrlsError ||
|
||||
!hotelUrls ||
|
||||
!cityUrls ||
|
||||
!countryUrls
|
||||
) {
|
||||
throw new Error("Unable to fetch location URLs")
|
||||
}
|
||||
|
||||
const hotelsAndCities = activeLocations
|
||||
.map((location) => {
|
||||
let url: string | undefined
|
||||
|
||||
if (location.type === "cities") {
|
||||
url = cityUrls.find(
|
||||
(c) =>
|
||||
c.city &&
|
||||
location.cityIdentifier &&
|
||||
c.city === location.cityIdentifier
|
||||
)?.url
|
||||
}
|
||||
|
||||
if (location.type === "hotels") {
|
||||
url = hotelUrls.find(
|
||||
(h) => h.hotelId && location.id && h.hotelId === location.id
|
||||
)?.url
|
||||
}
|
||||
|
||||
return { ...location, url }
|
||||
})
|
||||
.map(mapLocationToAutoCompleteLocation)
|
||||
.filter(isDefined)
|
||||
|
||||
const countryAutoCompleteLocations = countries.data.map((country) => {
|
||||
const url = countryUrls.find(
|
||||
(c) =>
|
||||
c.country &&
|
||||
ApiCountry[lang][c.country as Country] === country.name
|
||||
)?.url
|
||||
|
||||
return {
|
||||
id: country.id,
|
||||
name: country.name,
|
||||
type: "countries",
|
||||
searchTokens: [country.name],
|
||||
destination: "",
|
||||
url,
|
||||
} satisfies AutoCompleteLocation
|
||||
})
|
||||
|
||||
return [...hotelsAndCities, ...countryAutoCompleteLocations]
|
||||
},
|
||||
"1d"
|
||||
)
|
||||
const locations: AutoCompleteLocation[] =
|
||||
await getAutoCompleteDestinationsData({
|
||||
lang,
|
||||
serviceToken: ctx.serviceToken,
|
||||
})
|
||||
|
||||
const hits = filterAndCategorizeAutoComplete({
|
||||
locations: locations,
|
||||
@@ -176,3 +84,110 @@ function isCity(
|
||||
): location is AutoCompleteLocation & { type: "cities" } {
|
||||
return !!location && location.type === "cities"
|
||||
}
|
||||
|
||||
export async function getAutoCompleteDestinationsData({
|
||||
lang,
|
||||
serviceToken,
|
||||
warmup = false,
|
||||
}: {
|
||||
lang: Lang
|
||||
serviceToken: string
|
||||
warmup?: boolean
|
||||
}) {
|
||||
const cacheClient = await getCacheClient()
|
||||
return await cacheClient.cacheOrGet(
|
||||
`autocomplete:destinations:locations:${lang}`,
|
||||
async () => {
|
||||
const hotelUrlsPromise = safeTry(getHotelPageUrls(lang))
|
||||
const cityUrlsPromise = safeTry(getCityPageUrls(lang))
|
||||
const countryUrlsPromise = safeTry(getCountryPageUrls(lang))
|
||||
const countries = await getCountries({
|
||||
lang: lang,
|
||||
serviceToken,
|
||||
})
|
||||
|
||||
if (!countries) {
|
||||
throw new Error("Unable to fetch countries")
|
||||
}
|
||||
|
||||
const countryNames = countries.data.map((country) => country.name)
|
||||
const citiesByCountry = await getCitiesByCountry({
|
||||
countries: countryNames,
|
||||
serviceToken: serviceToken,
|
||||
lang,
|
||||
})
|
||||
|
||||
const locations = await getLocations({
|
||||
lang: lang,
|
||||
serviceToken: serviceToken,
|
||||
citiesByCountry: citiesByCountry,
|
||||
})
|
||||
|
||||
const activeLocations = locations.filter((location) => {
|
||||
return (
|
||||
location.type === "cities" ||
|
||||
(location.type === "hotels" && location.isActive)
|
||||
)
|
||||
})
|
||||
|
||||
const [hotelUrls, hotelUrlsError] = await hotelUrlsPromise
|
||||
const [cityUrls, cityUrlsError] = await cityUrlsPromise
|
||||
const [countryUrls, countryUrlsError] = await countryUrlsPromise
|
||||
|
||||
if (
|
||||
hotelUrlsError ||
|
||||
cityUrlsError ||
|
||||
countryUrlsError ||
|
||||
!hotelUrls ||
|
||||
!cityUrls ||
|
||||
!countryUrls
|
||||
) {
|
||||
throw new Error("Unable to fetch location URLs")
|
||||
}
|
||||
|
||||
const hotelsAndCities = activeLocations
|
||||
.map((location) => {
|
||||
let url: string | undefined
|
||||
|
||||
if (location.type === "cities") {
|
||||
url = cityUrls.find(
|
||||
(c) =>
|
||||
c.city &&
|
||||
location.cityIdentifier &&
|
||||
c.city === location.cityIdentifier
|
||||
)?.url
|
||||
}
|
||||
|
||||
if (location.type === "hotels") {
|
||||
url = hotelUrls.find(
|
||||
(h) => h.hotelId && location.id && h.hotelId === location.id
|
||||
)?.url
|
||||
}
|
||||
|
||||
return { ...location, url }
|
||||
})
|
||||
.map(mapLocationToAutoCompleteLocation)
|
||||
.filter(isDefined)
|
||||
|
||||
const countryAutoCompleteLocations = countries.data.map((country) => {
|
||||
const url = countryUrls.find(
|
||||
(c) =>
|
||||
c.country && ApiCountry[lang][c.country as Country] === country.name
|
||||
)?.url
|
||||
|
||||
return {
|
||||
id: country.id,
|
||||
name: country.name,
|
||||
type: "countries",
|
||||
searchTokens: [country.name],
|
||||
destination: "",
|
||||
url,
|
||||
} satisfies AutoCompleteLocation
|
||||
})
|
||||
|
||||
return [...hotelsAndCities, ...countryAutoCompleteLocations]
|
||||
},
|
||||
"1d",
|
||||
{ cacheStrategy: warmup ? "fetch-then-cache" : "cache-first" }
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user