@@ -15,6 +15,14 @@ import { Session } from "../session"
1515
1616export namespace File {
1717 const log = Log . create ( { service : "file" } )
18+ type SearchResult = { files : string [ ] ; dirs : string [ ] }
19+ type ExternalCache = { key : string ; time : number ; value : SearchResult }
20+ const EXTERNAL_CACHE_TTL = 2_000
21+ const externalCache = new Map < string , ExternalCache > ( )
22+
23+ function empty ( ) : SearchResult {
24+ return { files : [ ] , dirs : [ ] }
25+ }
1826
1927 export const Info = z
2028 . object ( {
@@ -333,13 +341,12 @@ export namespace File {
333341 }
334342
335343 const state = Instance . state ( async ( ) => {
336- type Entry = { files : string [ ] ; dirs : string [ ] }
337- let cache : Entry = { files : [ ] , dirs : [ ] }
344+ let cache : SearchResult = empty ( )
338345 let fetching = false
339346
340347 const isGlobalHome = Instance . directory === Global . Path . home && Instance . project . id === "global"
341348
342- const fn = async ( result : Entry ) => {
349+ const fn = async ( result : SearchResult ) => {
343350 // Disable scanning if in root of file system
344351 if ( Instance . directory === path . parse ( Instance . directory ) . root ) return
345352 fetching = true
@@ -401,10 +408,7 @@ export namespace File {
401408 return {
402409 async files ( ) {
403410 if ( ! fetching ) {
404- fn ( {
405- files : [ ] ,
406- dirs : [ ] ,
407- } )
411+ fn ( empty ( ) )
408412 }
409413 return cache
410414 } ,
@@ -620,10 +624,13 @@ export namespace File {
620624 }
621625
622626 async function external ( sessionID ?: string ) {
623- if ( ! sessionID ) return { files : [ ] , dirs : [ ] }
627+ if ( ! sessionID ) return empty ( )
624628
625629 const session = await Session . get ( sessionID ) . catch ( ( ) => undefined )
626- if ( ! session ?. permission ) return { files : [ ] , dirs : [ ] }
630+ if ( ! session ?. permission ) {
631+ externalCache . delete ( sessionID )
632+ return empty ( )
633+ }
627634
628635 const dirs = Array . from (
629636 new Set (
@@ -632,9 +639,18 @@ export namespace File {
632639 . map ( ( rule ) => externalDirectory ( rule . pattern ) )
633640 . filter ( ( rule ) : rule is string => Boolean ( rule ) ) ,
634641 ) ,
635- )
642+ ) . toSorted ( )
636643
637- if ( ! dirs . length ) return { files : [ ] , dirs : [ ] }
644+ const key = dirs . join ( "\0" )
645+ const now = Date . now ( )
646+ const cached = externalCache . get ( sessionID )
647+ if ( cached && cached . key === key && now - cached . time < EXTERNAL_CACHE_TTL ) return cached . value
648+
649+ if ( ! dirs . length ) {
650+ const value = empty ( )
651+ externalCache . set ( sessionID , { key, time : now , value } )
652+ return value
653+ }
638654
639655 const files : string [ ] = [ ]
640656 const folders = new Set < string > ( )
@@ -663,10 +679,12 @@ export namespace File {
663679 }
664680 }
665681
666- return {
682+ const value = {
667683 files : Array . from ( new Set ( files ) ) ,
668684 dirs : Array . from ( folders ) ,
669685 }
686+ externalCache . set ( sessionID , { key, time : now , value } )
687+ return value
670688 }
671689
672690 export async function search ( input : {
0 commit comments