1- import { TaskQueueType } from "@trigger.dev/database" ;
1+ import type { RunEngine } from "@internal/run-engine" ;
2+ import { Prisma , TaskQueueType } from "@trigger.dev/database" ;
3+ import { type PrismaClientOrTransaction } from "~/db.server" ;
24import { type AuthenticatedEnvironment } from "~/services/apiAuth.server" ;
35import { determineEngineVersion } from "~/v3/engineVersion.server" ;
46import { engine } from "~/v3/runEngine.server" ;
57import { BasePresenter } from "./basePresenter.server" ;
68import { toQueueItem } from "./QueueRetrievePresenter.server" ;
79
8- const DEFAULT_ITEMS_PER_PAGE = 25 ;
10+ type QueueListEngine = Pick < RunEngine , "lengthOfQueues" | "currentConcurrencyOfQueues" > ;
11+
12+ export const QUEUE_LIST_DEFAULT_ITEMS_PER_PAGE = 25 ;
913const MAX_ITEMS_PER_PAGE = 100 ;
1014
1115const typeToDBQueueType : Record < "task" | "custom" , TaskQueueType > = {
1216 task : TaskQueueType . VIRTUAL ,
1317 custom : TaskQueueType . NAMED ,
1418} ;
1519
20+ export type QueueListFilteredPagination = {
21+ mode : "filtered" ;
22+ currentPage : number ;
23+ hasMore : boolean ;
24+ } ;
25+
26+ export type QueueListUnfilteredPagination = {
27+ mode : "unfiltered" ;
28+ currentPage : number ;
29+ totalPages : number ;
30+ count : number ;
31+ } ;
32+
33+ export type QueueListPagination = QueueListFilteredPagination | QueueListUnfilteredPagination ;
34+
35+ export type OffsetLimitPagination = {
36+ currentPage : number ;
37+ totalPages : number ;
38+ count : number ;
39+ } ;
40+
41+ /** Maps presenter pagination to the public API / SDK offset-limit contract. */
42+ export function toOffsetLimitQueueListPagination (
43+ pagination : QueueListPagination ,
44+ options : { itemsOnPage : number ; perPage : number }
45+ ) : OffsetLimitPagination {
46+ if ( pagination . mode === "unfiltered" ) {
47+ return {
48+ currentPage : pagination . currentPage ,
49+ totalPages : pagination . totalPages ,
50+ count : pagination . count ,
51+ } ;
52+ }
53+
54+ return {
55+ currentPage : pagination . currentPage ,
56+ totalPages : pagination . hasMore ? pagination . currentPage + 1 : pagination . currentPage ,
57+ count :
58+ ( pagination . currentPage - 1 ) * options . perPage +
59+ options . itemsOnPage +
60+ ( pagination . hasMore ? 1 : 0 ) ,
61+ } ;
62+ }
63+
64+ function buildQueueListWhere (
65+ environmentId : string ,
66+ query : string | undefined ,
67+ type : "task" | "custom" | undefined
68+ ) : Prisma . TaskQueueWhereInput {
69+ const trimmedQuery = query ?. trim ( ) ;
70+
71+ return {
72+ runtimeEnvironmentId : environmentId ,
73+ version : "V2" ,
74+ name : trimmedQuery
75+ ? {
76+ contains : trimmedQuery ,
77+ mode : "insensitive" ,
78+ }
79+ : undefined ,
80+ type : type ? typeToDBQueueType [ type ] : undefined ,
81+ } ;
82+ }
83+
1684export class QueueListPresenter extends BasePresenter {
1785 private readonly perPage : number ;
86+ private readonly engineClient : QueueListEngine ;
1887
19- constructor ( perPage : number = DEFAULT_ITEMS_PER_PAGE ) {
20- super ( ) ;
88+ constructor (
89+ perPage : number = QUEUE_LIST_DEFAULT_ITEMS_PER_PAGE ,
90+ prismaClient ?: PrismaClientOrTransaction ,
91+ replicaClient ?: PrismaClientOrTransaction ,
92+ engineClient : QueueListEngine = engine
93+ ) {
94+ super ( prismaClient , replicaClient ) ;
2195 this . perPage = Math . min ( perPage , MAX_ITEMS_PER_PAGE ) ;
96+ this . engineClient = engineClient ;
2297 }
2398
2499 public async call ( {
@@ -33,26 +108,14 @@ export class QueueListPresenter extends BasePresenter {
33108 perPage ?: number ;
34109 type ?: "task" | "custom" ;
35110 } ) {
36- const hasFilters = ( query !== undefined && query . length > 0 ) || type !== undefined ;
37-
38- // Get total count for pagination
39- const totalQueues = await this . _replica . taskQueue . count ( {
40- where : {
41- runtimeEnvironmentId : environment . id ,
42- version : "V2" ,
43- name : query
44- ? {
45- contains : query ,
46- mode : "insensitive" ,
47- }
48- : undefined ,
49- type : type ? typeToDBQueueType [ type ] : undefined ,
50- } ,
51- } ) ;
111+ const hasFilters = Boolean ( query ?. trim ( ) ) || type !== undefined ;
52112
53- //check the engine is the correct version
54113 const engineVersion = await determineEngineVersion ( { environment } ) ;
55114 if ( engineVersion === "V1" ) {
115+ const totalQueues = await this . _replica . taskQueue . count ( {
116+ where : buildQueueListWhere ( environment . id , query , type ) ,
117+ } ) ;
118+
56119 if ( totalQueues === 0 ) {
57120 const oldQueue = await this . _replica . taskQueue . findFirst ( {
58121 where : {
@@ -78,10 +141,30 @@ export class QueueListPresenter extends BasePresenter {
78141 } ;
79142 }
80143
144+ if ( hasFilters ) {
145+ const { queues, hasMore } = await this . getFilteredQueues ( environment , query , page , type ) ;
146+
147+ return {
148+ success : true as const ,
149+ queues,
150+ pagination : {
151+ mode : "filtered" as const ,
152+ currentPage : page ,
153+ hasMore,
154+ } ,
155+ hasFilters,
156+ } ;
157+ }
158+
159+ const totalQueues = await this . _replica . taskQueue . count ( {
160+ where : buildQueueListWhere ( environment . id , query , type ) ,
161+ } ) ;
162+
81163 return {
82164 success : true as const ,
83- queues : await this . getQueuesWithPagination ( environment , query , page , type ) ,
165+ queues : await this . getUnfilteredQueues ( environment , page , type ) ,
84166 pagination : {
167+ mode : "unfiltered" as const ,
85168 currentPage : page ,
86169 totalPages : Math . ceil ( totalQueues / this . perPage ) ,
87170 count : totalQueues ,
@@ -91,24 +174,47 @@ export class QueueListPresenter extends BasePresenter {
91174 } ;
92175 }
93176
94- private async getQueuesWithPagination (
177+ private async getFilteredQueues (
95178 environment : AuthenticatedEnvironment ,
96179 query : string | undefined ,
97180 page : number ,
98181 type : "task" | "custom" | undefined
99182 ) {
100183 const queues = await this . _replica . taskQueue . findMany ( {
101- where : {
102- runtimeEnvironmentId : environment . id ,
103- version : "V2" ,
104- name : query
105- ? {
106- contains : query ,
107- mode : "insensitive" ,
108- }
109- : undefined ,
110- type : type ? typeToDBQueueType [ type ] : undefined ,
184+ where : buildQueueListWhere ( environment . id , query , type ) ,
185+ select : {
186+ friendlyId : true ,
187+ name : true ,
188+ orderableName : true ,
189+ concurrencyLimit : true ,
190+ concurrencyLimitBase : true ,
191+ concurrencyLimitOverriddenAt : true ,
192+ concurrencyLimitOverriddenBy : true ,
193+ type : true ,
194+ paused : true ,
111195 } ,
196+ orderBy : {
197+ orderableName : "asc" ,
198+ } ,
199+ skip : ( page - 1 ) * this . perPage ,
200+ take : this . perPage + 1 ,
201+ } ) ;
202+
203+ const hasMore = queues . length > this . perPage ;
204+
205+ return {
206+ queues : await this . enrichQueues ( environment , queues . slice ( 0 , this . perPage ) ) ,
207+ hasMore,
208+ } ;
209+ }
210+
211+ private async getUnfilteredQueues (
212+ environment : AuthenticatedEnvironment ,
213+ page : number ,
214+ type : "task" | "custom" | undefined
215+ ) {
216+ const queues = await this . _replica . taskQueue . findMany ( {
217+ where : buildQueueListWhere ( environment . id , undefined , type ) ,
112218 select : {
113219 friendlyId : true ,
114220 name : true ,
@@ -127,12 +233,29 @@ export class QueueListPresenter extends BasePresenter {
127233 take : this . perPage ,
128234 } ) ;
129235
236+ return this . enrichQueues ( environment , queues ) ;
237+ }
238+
239+ private async enrichQueues (
240+ environment : AuthenticatedEnvironment ,
241+ queues : {
242+ friendlyId : string ;
243+ name : string ;
244+ orderableName : string | null ;
245+ concurrencyLimit : number | null ;
246+ concurrencyLimitBase : number | null ;
247+ concurrencyLimitOverriddenAt : Date | null ;
248+ concurrencyLimitOverriddenBy : string | null ;
249+ type : TaskQueueType ;
250+ paused : boolean ;
251+ } [ ]
252+ ) {
130253 const results = await Promise . all ( [
131- engine . lengthOfQueues (
254+ this . engineClient . lengthOfQueues (
132255 environment ,
133256 queues . map ( ( q ) => q . name )
134257 ) ,
135- engine . currentConcurrencyOfQueues (
258+ this . engineClient . currentConcurrencyOfQueues (
136259 environment ,
137260 queues . map ( ( q ) => q . name )
138261 ) ,
@@ -149,7 +272,6 @@ export class QueueListPresenter extends BasePresenter {
149272
150273 const overriddenByMap = new Map ( overriddenByUsers . map ( ( u ) => [ u . id , u ] ) ) ;
151274
152- // Transform queues to include running and queued counts
153275 return queues . map ( ( queue ) =>
154276 toQueueItem ( {
155277 friendlyId : queue . friendlyId ,
0 commit comments