@@ -24,6 +24,8 @@ import {
2424 HttpCallbackResultTypeFromSchema ,
2525 HttpCallbackResult ,
2626 tryCatch ,
27+ inferSchemaIn ,
28+ getSchemaParseFn ,
2729} from "@trigger.dev/core/v3" ;
2830import { tracer } from "./tracer.js" ;
2931import { conditionallyImportAndParsePacket } from "@trigger.dev/core/v3/utils/ioSerialization" ;
@@ -718,7 +720,7 @@ export const wait = {
718720 } ,
719721 {
720722 attributes : {
721- [ SemanticInternalAttributes . STYLE_ICON ] : "wait-http-callback " ,
723+ [ SemanticInternalAttributes . STYLE_ICON ] : "wait" ,
722724 [ SemanticInternalAttributes . ENTITY_TYPE ] : "waitpoint" ,
723725 [ SemanticInternalAttributes . ENTITY_ID ] : waitpoint . id ,
724726 ...accessoryAttributes ( {
@@ -760,6 +762,123 @@ export const wait = {
760762 // 10. Receive the result here and import the packet, then get the result in the right format
761763 // 11. Make unwrap work
762764 } ,
765+ async forHttpCallbackWithSchema < TSchema extends HttpCallbackSchema > (
766+ schema : TSchema ,
767+ callback : ( url : string ) => Promise < void > ,
768+ options ?: CreateWaitpointTokenRequestBody & {
769+ releaseConcurrency ?: boolean ;
770+ } ,
771+ requestOptions ?: ApiRequestOptions
772+ ) : Promise < HttpCallbackResult < HttpCallbackResultTypeFromSchema < TSchema > > > {
773+ const ctx = taskContext . ctx ;
774+
775+ if ( ! ctx ) {
776+ throw new Error ( "wait.forHttpCallback can only be used from inside a task.run()" ) ;
777+ }
778+
779+ const apiClient = apiClientManager . clientOrThrow ( ) ;
780+
781+ const waitpoint = await apiClient . createWaitpointHttpCallback ( options ?? { } , requestOptions ) ;
782+
783+ return tracer . startActiveSpan (
784+ `wait.forHttpCallback()` ,
785+ async ( span ) => {
786+ const [ error ] = await tryCatch ( callback ( waitpoint . url ) ) ;
787+
788+ if ( error ) {
789+ throw new Error ( `You threw an error in your callback: ${ error . message } ` , {
790+ cause : error ,
791+ } ) ;
792+ }
793+
794+ const response = await apiClient . waitForWaitpointToken ( {
795+ runFriendlyId : ctx . run . id ,
796+ waitpointFriendlyId : waitpoint . id ,
797+ releaseConcurrency : options ?. releaseConcurrency ,
798+ } ) ;
799+
800+ if ( ! response . success ) {
801+ throw new Error ( `Failed to wait for wait for HTTP callback ${ waitpoint . id } ` ) ;
802+ }
803+
804+ const result = await runtime . waitUntil ( waitpoint . id ) ;
805+
806+ const data = result . output
807+ ? await conditionallyImportAndParsePacket (
808+ { data : result . output , dataType : result . outputType ?? "application/json" } ,
809+ apiClient
810+ )
811+ : undefined ;
812+
813+ if ( result . ok ) {
814+ try {
815+ const parser = schema ? getSchemaParseFn < inferSchemaIn < TSchema > > ( schema ) : undefined ;
816+
817+ if ( ! parser ) {
818+ throw new Error ( "No parser found for schema" ) ;
819+ }
820+
821+ const parsedOutput = await parser ( data ) ;
822+
823+ return {
824+ ok : result . ok ,
825+ output : parsedOutput ,
826+ } ;
827+ } catch ( error ) {
828+ const err = error instanceof Error ? error : new Error ( String ( error ) ) ;
829+ span . recordException ( err ) ;
830+ span . setStatus ( {
831+ code : SpanStatusCode . ERROR ,
832+ } ) ;
833+
834+ return {
835+ ok : false ,
836+ error : err ,
837+ } ;
838+ }
839+ } else {
840+ const error = new WaitpointTimeoutError ( data . message ) ;
841+
842+ span . recordException ( error ) ;
843+ span . setStatus ( {
844+ code : SpanStatusCode . ERROR ,
845+ } ) ;
846+
847+ return {
848+ ok : result . ok ,
849+ error,
850+ } ;
851+ }
852+ } ,
853+ {
854+ attributes : {
855+ [ SemanticInternalAttributes . STYLE_ICON ] : "wait" ,
856+ [ SemanticInternalAttributes . ENTITY_TYPE ] : "waitpoint" ,
857+ [ SemanticInternalAttributes . ENTITY_ID ] : waitpoint . id ,
858+ ...accessoryAttributes ( {
859+ items : [
860+ {
861+ text : waitpoint . id ,
862+ variant : "normal" ,
863+ } ,
864+ ] ,
865+ style : "codepath" ,
866+ } ) ,
867+ id : waitpoint . id ,
868+ isCached : waitpoint . isCached ,
869+ idempotencyKey : options ?. idempotencyKey ,
870+ idempotencyKeyTTL : options ?. idempotencyKeyTTL ,
871+ timeout : options ?. timeout
872+ ? typeof options . timeout === "string"
873+ ? options . timeout
874+ : options . timeout . toISOString ( )
875+ : undefined ,
876+ tags : options ?. tags ,
877+ url : waitpoint . url ,
878+ } ,
879+ }
880+ ) ;
881+ } ,
763882} ;
764883
765884function nameForWaitOptions ( options : WaitForOptions ) : string {
0 commit comments