Skip to content

Commit a2e6bd5

Browse files
authored
refactor(reference): split materialization state (#28190)
1 parent 05ac345 commit a2e6bd5

1 file changed

Lines changed: 62 additions & 48 deletions

File tree

packages/opencode/src/reference/reference.ts

Lines changed: 62 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,11 @@ export type Resolved =
3333
type 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+
3941
export 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+
91146
export 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

Comments
 (0)