@@ -33,9 +33,11 @@ export type Resolved =
3333type State = {
3434 references : Resolved [ ]
3535 materializeAll : Effect . Effect < void >
36- materializeByPath : { path : string ; run : Effect . Effect < void > } [ ]
36+ materializeByPath : Materializer [ ]
3737}
3838
39+ type Materializer = { path : string ; run : Effect . Effect < void > }
40+
3941export interface Interface {
4042 readonly init : ( ) => Effect . Effect < void >
4143 readonly list : ( ) => Effect . Effect < Resolved [ ] >
@@ -88,6 +90,59 @@ function containsReferencePath(referencePath: string, target: string) {
8890 return AppFileSystem . contains ( normalizedTarget ( referencePath ) ?? referencePath , target )
8991}
9092
93+ function uniqueGitReferences ( references : Resolved [ ] ) {
94+ const seenPath = new Set < string > ( )
95+ return references . filter ( ( reference ) : reference is Extract < Resolved , { kind : "git" } > => {
96+ if ( reference . kind !== "git" ) return false
97+ if ( seenPath . has ( reference . path ) ) return false
98+ seenPath . add ( reference . path )
99+ return true
100+ } )
101+ }
102+
103+ function materializeReference ( cache : RepositoryCache . Interface , reference : Extract < Resolved , { kind : "git" } > ) {
104+ return cache . ensure ( { reference : reference . reference , branch : reference . branch , refresh : true } ) . pipe (
105+ Effect . asVoid ,
106+ Effect . catchCause ( ( cause ) =>
107+ Effect . logWarning ( "failed to materialize reference repository" ) . pipe (
108+ Effect . annotateLogs ( { name : reference . name , cause } ) ,
109+ ) ,
110+ ) ,
111+ )
112+ }
113+
114+ const materializers = Effect . fn ( "Reference.materializers" ) ( function * (
115+ cache : RepositoryCache . Interface ,
116+ references : Resolved [ ] ,
117+ ) {
118+ return yield * Effect . forEach (
119+ uniqueGitReferences ( references ) ,
120+ Effect . fnUntraced ( function * ( reference ) {
121+ return { path : reference . path , run : yield * Effect . cached ( materializeReference ( cache , reference ) ) }
122+ } ) ,
123+ { concurrency : "unbounded" } ,
124+ )
125+ } )
126+
127+ function materializeAll ( input : { flags : RuntimeFlags . Info ; materializers : Materializer [ ] } ) {
128+ if ( ! input . flags . experimentalScout ) return Effect . void
129+ return Effect . forEach (
130+ input . materializers ,
131+ Effect . fnUntraced ( function * ( item ) {
132+ yield * item . run
133+ } ) ,
134+ { concurrency : 4 , discard : true } ,
135+ )
136+ }
137+
138+ function materializeByPath ( materializers : Materializer [ ] , target : string ) {
139+ return materializers . find ( ( item ) => containsReferencePath ( item . path , target ) ) ?. run ?? Effect . void
140+ }
141+
142+ function containsGitReferencePath ( references : Resolved [ ] , target : string ) {
143+ return references . some ( ( reference ) => reference . kind === "git" && containsReferencePath ( reference . path , target ) )
144+ }
145+
91146export function resolve ( input : {
92147 name : string
93148 reference : ConfigReference . NormalizedEntry
@@ -141,46 +196,10 @@ export const layer = Layer.effect(
141196 directory : ctx . directory ,
142197 worktree : ctx . worktree ,
143198 } )
144- const seenPath = new Set < string > ( )
145- const gitReferences = references . filter ( ( reference ) : reference is Extract < Resolved , { kind : "git" } > => {
146- if ( reference . kind !== "git" ) return false
147- if ( seenPath . has ( reference . path ) ) return false
148- seenPath . add ( reference . path )
149- return true
150- } )
151- const materializeByPath = yield * Effect . forEach (
152- gitReferences ,
153- Effect . fnUntraced ( function * ( reference ) {
154- const run = yield * Effect . cached (
155- cache . ensure ( { reference : reference . reference , branch : reference . branch , refresh : true } ) . pipe (
156- Effect . asVoid ,
157- Effect . catchCause ( ( cause ) =>
158- Effect . logWarning ( "failed to materialize reference repository" ) . pipe (
159- Effect . annotateLogs ( { name : reference . name , cause } ) ,
160- ) ,
161- ) ,
162- ) ,
163- )
164- return { path : reference . path , run }
165- } ) ,
166- { concurrency : "unbounded" } ,
167- )
168-
169- const materializeAll = yield * Effect . cached (
170- flags . experimentalScout
171- ? Effect . gen ( function * ( ) {
172- yield * Effect . forEach (
173- materializeByPath ,
174- Effect . fnUntraced ( function * ( item ) {
175- yield * item . run
176- } ) ,
177- { concurrency : 4 , discard : true } ,
178- )
179- } )
180- : Effect . void ,
181- )
182-
183- return { references, materializeAll, materializeByPath }
199+ const materializeByPath = yield * materializers ( cache , references )
200+ const materializeAllCached = yield * Effect . cached ( materializeAll ( { flags, materializers : materializeByPath } ) )
201+
202+ return { references, materializeAll : materializeAllCached , materializeByPath }
184203 } ) ,
185204 )
186205
@@ -199,18 +218,13 @@ export const layer = Layer.effect(
199218 if ( ! flags . experimentalScout ) return
200219 const full = normalizedTarget ( target )
201220 if ( ! full ) return yield * InstanceState . useEffect ( state , ( s ) => s . materializeAll )
202- return yield * InstanceState . useEffect (
203- state ,
204- ( s ) => s . materializeByPath . find ( ( item ) => containsReferencePath ( item . path , full ) ) ?. run ?? Effect . void ,
205- )
221+ return yield * InstanceState . useEffect ( state , ( s ) => materializeByPath ( s . materializeByPath , full ) )
206222 } ) ,
207223 contains : Effect . fn ( "Reference.contains" ) ( function * ( target ?: string ) {
208224 if ( ! flags . experimentalScout ) return false
209225 const full = normalizedTarget ( target )
210226 if ( ! full ) return false
211- return yield * InstanceState . use ( state , ( s ) =>
212- s . references . some ( ( reference ) => reference . kind === "git" && containsReferencePath ( reference . path , full ) ) ,
213- )
227+ return yield * InstanceState . use ( state , ( s ) => containsGitReferencePath ( s . references , full ) )
214228 } ) ,
215229 } )
216230 } ) ,
0 commit comments