22
33import { sew } from "@/actions" ;
44import { withOptionalAuthV2 } from "@/withAuthV2" ;
5- import { ZodAccelerator } from "@duplojs/zod-accelerator" ;
65import { PrismaClient , Repo } from "@sourcebot/db" ;
76import { base64Decode , createLogger } from "@sourcebot/shared" ;
87import { StatusCodes } from "http-status-codes" ;
9- import z from "zod" ;
108import { ErrorCode } from "../../lib/errorCodes" ;
119import { invalidZoektResponse , ServiceError } from "../../lib/serviceError" ;
1210import { isServiceError , measure } from "../../lib/utils" ;
1311import { SearchRequest , SearchResponse , SourceRange } from "./types" ;
1412import { zoektFetch } from "./zoektClient" ;
15- import { zoektSearchResponseSchema } from "./zoektSchema" ;
13+ import { ZoektSearchResponse } from "./zoektSchema" ;
1614
17- const acceleratedZoektSearchResponseSchema = ZodAccelerator . build ( zoektSearchResponseSchema ) ;
1815const logger = createLogger ( "searchApi" ) ;
1916
2017// List of supported query prefixes in zoekt.
@@ -220,7 +217,7 @@ export const search = async ({ query, matches, contextLines, whole }: SearchRequ
220217 return invalidZoektResponse ( searchResponse ) ;
221218 }
222219
223- const transformZoektSearchResponse = async ( { Result } : z . infer < typeof zoektSearchResponseSchema > ) => {
220+ const transformZoektSearchResponse = async ( { Result } : ZoektSearchResponse ) => {
224221 // @note (2025-05-12): in zoekt, repositories are identified by the `RepositoryID` field
225222 // which corresponds to the `id` in the Repo table. In order to efficiently fetch repository
226223 // metadata when transforming (potentially thousands) of file matches, we aggregate a unique
@@ -394,25 +391,22 @@ export const search = async ({ query, matches, contextLines, whole }: SearchRequ
394391 false
395392 ) ;
396393
397- const { data : zoektResponse , durationMs : parseZoektResponseDurationMs } = await measure (
398- ( ) => acceleratedZoektSearchResponseSchema . parseAsync ( rawZoektResponse ) ,
399- "parse_zoekt_response" ,
400- false
401- ) ;
394+ // @note : We do not use zod parseAsync here since in cases where the
395+ // response is large (> 40MB), there can be significant performance issues.
396+ const zoektResponse = rawZoektResponse as ZoektSearchResponse ;
402397
403398 const { data : response , durationMs : transformZoektResponseDurationMs } = await measure (
404399 ( ) => transformZoektSearchResponse ( zoektResponse ) ,
405400 "transform_zoekt_response" ,
406401 false
407402 ) ;
408403
409- const totalDurationMs = fetchDurationMs + parseJsonDurationMs + parseZoektResponseDurationMs + transformZoektResponseDurationMs ;
404+ const totalDurationMs = fetchDurationMs + parseJsonDurationMs + transformZoektResponseDurationMs ;
410405
411406 // Debug log: timing breakdown
412407 const timings = [
413408 { name : "zoekt_fetch" , duration : fetchDurationMs } ,
414409 { name : "parse_json" , duration : parseJsonDurationMs } ,
415- { name : "parse_zoekt_response" , duration : parseZoektResponseDurationMs } ,
416410 { name : "transform_zoekt_response" , duration : transformZoektResponseDurationMs } ,
417411 ] ;
418412
@@ -430,7 +424,6 @@ export const search = async ({ query, matches, contextLines, whole }: SearchRequ
430424 __debug_timings : {
431425 zoekt_fetch : fetchDurationMs ,
432426 parse_json : parseJsonDurationMs ,
433- parse_zoekt_response : parseZoektResponseDurationMs ,
434427 transform_zoekt_response : transformZoektResponseDurationMs ,
435428 }
436429 } satisfies SearchResponse ;
0 commit comments