@@ -127,15 +127,15 @@ const SECURITY_HEADERS = {
127127} ;
128128
129129export default {
130- async fetch ( request , env ) {
130+ async fetch ( request , env , ctx ) {
131131 const url = new URL ( request . url ) ;
132132 try {
133133 if ( url . pathname === "/login" ) return await startLogin ( request , env ) ;
134134 if ( url . pathname === "/callback" ) return await finishLogin ( request , env ) ;
135135 if ( url . pathname === "/admin" ) return await adminPage ( request , env ) ;
136136 if ( url . pathname === "/api/session" ) return json ( await sessionPayload ( request , env ) ) ;
137137 if ( url . pathname === "/api/strategy-profiles" ) return json ( await strategyProfilesPayload ( env ) ) ;
138- if ( url . pathname === "/api/config" ) return json ( await configPayload ( request , env ) ) ;
138+ if ( url . pathname === "/api/config" ) return json ( await configPayload ( request , env , ctx ) ) ;
139139 if ( url . pathname === "/api/admin/config" && request . method === "GET" ) {
140140 return await adminConfigResponse ( request , env ) ;
141141 }
@@ -575,30 +575,49 @@ async function loadPlatformMeta() {
575575 return merged ;
576576}
577577
578- async function configPayload ( request , env ) {
578+ // In-memory cache for the lifetime of this Worker isolate.
579+ // Falls back to KV on cold starts; KV write uses ctx.waitUntil
580+ // so it survives past the response.
581+ let _memCurrentStrategies = null ;
582+ let _memCurrentStrategiesTs = 0 ;
583+
584+ async function configPayload ( request , env , ctx ) {
579585 const session = await readSession ( request , env ) ;
580586 const meta = await loadPlatformMeta ( ) ;
581587 if ( ! session ?. allowed ) return { accountOptions : null , platformMeta : meta } ;
582588 const accountConfig = await loadAccountOptionsConfig ( env ) ;
583589 const strategyProfiles = await loadStrategyProfilesConfig ( env ) ;
584590
585591 let currentStrategies = null ;
586- if ( hasConfigStore ( env ) ) {
592+
593+ // 1) In-memory cache (fastest — same Worker isolate)
594+ if ( _memCurrentStrategies && ( Date . now ( ) - _memCurrentStrategiesTs ) < CURRENT_STRATEGIES_CACHE_TTL_MS ) {
595+ currentStrategies = _memCurrentStrategies ;
596+ }
597+
598+ // 2) KV cache (survives cold starts)
599+ if ( ! currentStrategies && hasConfigStore ( env ) ) {
587600 const cached = await readConfigJson ( env , CURRENT_STRATEGIES_CACHE_KEY ) ;
588601 if ( cached ?. ts && ( Date . now ( ) - cached . ts ) < CURRENT_STRATEGIES_CACHE_TTL_MS && cached . data ) {
589602 currentStrategies = cached . data ;
603+ _memCurrentStrategies = cached . data ;
604+ _memCurrentStrategiesTs = cached . ts ;
590605 }
591606 }
607+
608+ // 3) Cache miss — fetch from GitHub
592609 if ( ! currentStrategies ) {
593610 currentStrategies = await loadCurrentStrategiesSafely ( accountConfig . options , env ) ;
594- if ( hasConfigStore ( env ) ) {
595- // fire-and-forget: don't block the response on cache write
596- writeConfigJson ( env , CURRENT_STRATEGIES_CACHE_KEY , {
597- ts : Date . now ( ) ,
611+ _memCurrentStrategies = currentStrategies ;
612+ _memCurrentStrategiesTs = Date . now ( ) ;
613+ if ( hasConfigStore ( env ) && ctx ) {
614+ ctx . waitUntil ( writeConfigJson ( env , CURRENT_STRATEGIES_CACHE_KEY , {
615+ ts : _memCurrentStrategiesTs ,
598616 data : currentStrategies ,
599- } ) . catch ( ( ) => { } ) ;
617+ } ) ) ;
600618 }
601619 }
620+
602621 return {
603622 accountOptions : accountConfig . options ,
604623 platformRepositories : platformRepositories ( env ) ,
0 commit comments