@@ -52,7 +52,9 @@ export default {
5252 if ( COLLECTION_TYPES [ type ] ) {
5353 // Check if user wants full data via ?full=true
5454 const full = url . searchParams . get ( 'full' ) === 'true' ;
55- return await handleList ( type , env , ctx , full ) ;
55+ const limit = parseInt ( url . searchParams . get ( 'limit' ) ) || undefined ;
56+ const offset = parseInt ( url . searchParams . get ( 'offset' ) ) || 0 ;
57+ return await handleList ( type , env , ctx , full , limit , offset ) ;
5658 }
5759
5860 return jsonResponse ( { error : `Unknown data type: ${ type } ` } , 404 ) ;
@@ -191,8 +193,10 @@ async function handleGetItem(type, id, env, ctx) {
191193 * List all items of a type
192194 * Uses GitHub API to dynamically list directory contents
193195 * @param {boolean } full - If true, fetch and return full data for all items
196+ * @param {number } limit - Max items to return (default: 45 for full, all for list)
197+ * @param {number } offset - Skip this many items (for pagination)
194198 */
195- async function handleList ( type , env , ctx , full = false ) {
199+ async function handleList ( type , env , ctx , full = false , limit = undefined , offset = 0 ) {
196200 if ( ! COLLECTION_TYPES [ type ] ) {
197201 return jsonResponse ( { error : `Unknown collection type: ${ type } ` } , 404 ) ;
198202 }
@@ -222,43 +226,60 @@ async function handleList(type, env, ctx, full = false) {
222226 const files = await githubResponse . json ( ) ;
223227
224228 // Filter to only .json files
225- const jsonFiles = files
229+ const allJsonFiles = files
226230 . filter ( ( f ) => f . type === 'file' && f . name . endsWith ( '.json' ) && ! f . name . startsWith ( '_' ) )
227231 . map ( ( f ) => f . name . replace ( '.json' , '' ) )
228232 . sort ( ( a , b ) => a . localeCompare ( b ) ) ;
229233
234+ const totalItems = allJsonFiles . length ;
235+
236+ // Apply pagination
237+ let jsonFiles = allJsonFiles ;
238+ if ( offset > 0 ) {
239+ jsonFiles = jsonFiles . slice ( offset ) ;
240+ }
241+
230242 let data ;
231243
232244 if ( full ) {
233- // Cloudflare Workers has a 50 subrequest limit, so batch the fetches
234- const BATCH_SIZE = 50 ;
235- const allItems = [ ] ;
236-
237- for ( let i = 0 ; i < jsonFiles . length ; i += BATCH_SIZE ) {
238- const batch = jsonFiles . slice ( i , i + BATCH_SIZE ) ;
239- const batchPromises = batch . map ( async ( id ) => {
240- const itemUrl = `${ GITHUB_BASE } /${ dirPath } /${ id } .json` ;
241- const itemResponse = await fetch ( itemUrl , {
242- headers : { 'User-Agent' : 'ArcRaiders-API/1.0' } ,
243- } ) ;
244-
245- if ( itemResponse . ok ) {
246- return await itemResponse . json ( ) ;
247- }
248- return null ;
245+ // Cloudflare Workers free tier has 50 subrequest limit
246+ // We already used 1 for the GitHub API call, so we have 49 left
247+ const MAX_ITEMS = 45 ; // Leave some buffer
248+ const effectiveLimit = limit && limit < MAX_ITEMS ? limit : MAX_ITEMS ;
249+ const limitedFiles = jsonFiles . slice ( 0 , effectiveLimit ) ;
250+
251+ const itemPromises = limitedFiles . map ( async ( id ) => {
252+ const itemUrl = `${ GITHUB_BASE } /${ dirPath } /${ id } .json` ;
253+ const itemResponse = await fetch ( itemUrl , {
254+ headers : { 'User-Agent' : 'ArcRaiders-API/1.0' } ,
249255 } ) ;
250256
251- const batchResults = await Promise . all ( batchPromises ) ;
252- allItems . push ( ...batchResults . filter ( Boolean ) ) ;
253- }
257+ if ( itemResponse . ok ) {
258+ return await itemResponse . json ( ) ;
259+ }
260+ return null ;
261+ } ) ;
262+
263+ const itemsData = await Promise . all ( itemPromises ) ;
254264
255265 data = {
256266 type,
257- count : allItems . length ,
258- items : allItems ,
267+ total : totalItems ,
268+ count : itemsData . filter ( Boolean ) . length ,
269+ offset,
270+ limit : effectiveLimit ,
271+ items : itemsData . filter ( Boolean ) ,
259272 } ;
273+
274+ // Add pagination hints
275+ if ( offset + effectiveLimit < totalItems ) {
276+ data . next = `/v1/${ type } ?full=true&offset=${ offset + effectiveLimit } &limit=${ effectiveLimit } ` ;
277+ }
278+ if ( offset > 0 ) {
279+ data . prev = `/v1/${ type } ?full=true&offset=${ Math . max ( 0 , offset - effectiveLimit ) } &limit=${ effectiveLimit } ` ;
280+ }
260281 } else {
261- // Just return IDs and URLs (original behavior)
282+ // Just return IDs and URLs (original behavior, no limit )
262283 const items = jsonFiles . map ( ( id ) => ( {
263284 id,
264285 url : `/v1/${ type } /${ id } ` ,
0 commit comments