Merged in fix/warmup-autocomplete-data-2 (pull request #2218)

fix: chunked data overwrote it self

* fix: chunked data overwrote it self


Approved-by: Linus Flood
This commit is contained in:
Joakim Jäderberg
2025-05-26 09:39:48 +00:00
parent c963891ca7
commit b20c8ce42b
3 changed files with 98 additions and 74 deletions

View File

@@ -41,7 +41,6 @@ export const getDestinationsAutoCompleteRoute = safeProtectedServiceProcedure
.input(destinationsAutoCompleteInputSchema) .input(destinationsAutoCompleteInputSchema)
.query(async ({ ctx, input }): Promise<DestinationsAutoCompleteOutput> => { .query(async ({ ctx, input }): Promise<DestinationsAutoCompleteOutput> => {
const lang = input.lang || ctx.lang const lang = input.lang || ctx.lang
const locations: AutoCompleteLocation[] = const locations: AutoCompleteLocation[] =
await getAutoCompleteDestinationsData({ await getAutoCompleteDestinationsData({
lang, lang,
@@ -107,6 +106,7 @@ export async function getAutoCompleteDestinationsData({
}) })
if (!countries) { if (!countries) {
console.error("Unable to fetch countries")
throw new Error("Unable to fetch countries") throw new Error("Unable to fetch countries")
} }
@@ -142,6 +142,7 @@ export async function getAutoCompleteDestinationsData({
!cityUrls || !cityUrls ||
!countryUrls !countryUrls
) { ) {
console.error("Unable to fetch location URLs")
throw new Error("Unable to fetch location URLs") throw new Error("Unable to fetch location URLs")
} }

View File

@@ -253,7 +253,6 @@ export async function getLocations({
serviceToken: string serviceToken: string
}) { }) {
const cacheClient = await getCacheClient() const cacheClient = await getCacheClient()
return await cacheClient.cacheOrGet( return await cacheClient.cacheOrGet(
`${lang}:locations`.toLowerCase(), `${lang}:locations`.toLowerCase(),
async () => { async () => {
@@ -286,53 +285,53 @@ export async function getLocations({
console.error(verifiedLocations.error) console.error(verifiedLocations.error)
throw new Error("Unable to parse locations") throw new Error("Unable to parse locations")
} }
const chunkedLocations = chunk(verifiedLocations.data.data, 10) const chunkedLocations = chunk(verifiedLocations.data.data, 10)
let locations: z.infer<typeof locationsSchema>["data"] = [] let locations: z.infer<typeof locationsSchema>["data"] = []
for (const chunk of chunkedLocations) { for (const chunk of chunkedLocations) {
locations = [ const chunkLocations = await Promise.all(
...(await Promise.all( chunk.map(async (location) => {
chunk.map(async (location) => { if (location.type === "cities") {
if (location.type === "cities") { if (citiesByCountry) {
if (citiesByCountry) { const country = Object.keys(citiesByCountry).find((country) =>
const country = Object.keys(citiesByCountry).find((country) => citiesByCountry[country].find(
citiesByCountry[country].find( (loc) => loc.name === location.name
(loc) => loc.name === location.name
)
) )
if (country) { )
return { if (country) {
...location, return {
country, ...location,
} country,
} else {
console.info(
`Location cannot be found in any of the countries cities`
)
console.info(location)
}
}
} else if (location.type === "hotels") {
if (location.relationships.city?.url) {
const city = await getCity({
cityUrl: location.relationships.city.url,
serviceToken,
})
if (city) {
return deepmerge(location, {
relationships: {
city,
},
})
} }
} else {
console.info(
`Location cannot be found in any of the countries cities`
)
console.info(location)
} }
} }
} else if (location.type === "hotels") {
if (location.relationships.city?.url) {
const city = await getCity({
cityUrl: location.relationships.city.url,
serviceToken,
})
if (city) {
return deepmerge(location, {
relationships: {
city,
},
})
}
}
}
return location return location
}) })
)), )
]
locations.push(...chunkLocations)
} }
return locations return locations
@@ -523,44 +522,43 @@ export async function getHotelsByHotelIds({
const hotels: DestinationPagesHotelData[] = [] const hotels: DestinationPagesHotelData[] = []
for (const hotelIdChunk of chunkedHotelIds) { for (const hotelIdChunk of chunkedHotelIds) {
hotels.push( const chunkedHotels = await Promise.all(
...(await Promise.all( hotelIdChunk.map(async (hotelId) => {
hotelIdChunk.map(async (hotelId) => { const hotelResponse = await getHotel(
const hotelResponse = await getHotel( { hotelId, language: lang, isCardOnlyPayment: false },
{ hotelId, language: lang, isCardOnlyPayment: false }, serviceToken
serviceToken )
)
if (!hotelResponse) { if (!hotelResponse) {
throw new Error(`Hotel not found: ${hotelId}`) throw new Error(`Hotel not found: ${hotelId}`)
} }
const hotelPage = hotelPages.find( const hotelPage = hotelPages.find(
(page) => page.hotelId === hotelId (page) => page.hotelId === hotelId
) )
const { hotel, cities } = hotelResponse const { hotel, cities } = hotelResponse
const data: DestinationPagesHotelData = { const data: DestinationPagesHotelData = {
hotel: { hotel: {
id: hotel.id, id: hotel.id,
galleryImages: hotel.galleryImages, galleryImages: hotel.galleryImages,
name: hotel.name, name: hotel.name,
tripadvisor: hotel.ratings?.tripAdvisor?.rating, tripadvisor: hotel.ratings?.tripAdvisor?.rating,
detailedFacilities: hotel.detailedFacilities || [], detailedFacilities: hotel.detailedFacilities || [],
location: hotel.location, location: hotel.location,
hotelType: hotel.hotelType, hotelType: hotel.hotelType,
type: hotel.type, type: hotel.type,
address: hotel.address, address: hotel.address,
cityIdentifier: cities?.[0]?.cityIdentifier, cityIdentifier: cities?.[0]?.cityIdentifier,
hotelDescription: hotelDescription: hotel.hotelContent?.texts.descriptions?.short,
hotel.hotelContent?.texts.descriptions?.short, },
}, url: hotelPage?.url ?? "",
url: hotelPage?.url ?? "", }
}
return data return data
}) })
))
) )
hotels.push(...chunkedHotels)
} }
return hotels.filter( return hotels.filter(
(hotel): hotel is DestinationPagesHotelData => !!hotel (hotel): hotel is DestinationPagesHotelData => !!hotel

View File

@@ -0,0 +1,25 @@
import { describe, expect } from "@jest/globals"
import { chunk } from "./chunk"
describe("chunk", () => {
it("should split an array into equally sized chunks of specified size", () => {
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9]
const size = 3
const expected = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]
expect(chunk(array, size)).toEqual(expected)
})
it("should split an array into equally sized chunks of specified size", () => {
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9]
const size = 4
const expected = [[1, 2, 3, 4], [5, 6, 7, 8], [9]]
expect(chunk(array, size)).toEqual(expected)
})
})