mirror of
https://gitea.toothfairyai.com/ToothFairyAI/tf_code.git
synced 2026-03-30 05:43:55 +00:00
56 lines
2.0 KiB
TypeScript
56 lines
2.0 KiB
TypeScript
import { Effect, Layer, LayerMap, ServiceMap } from "effect"
|
|
import { registerDisposer } from "./instance-registry"
|
|
import { InstanceContext } from "./instance-context"
|
|
import { ProviderAuthService } from "@/provider/auth-service"
|
|
import { QuestionService } from "@/question/service"
|
|
import { PermissionService } from "@/permission/service"
|
|
import { FileWatcherService } from "@/file/watcher"
|
|
import { VcsService } from "@/project/vcs"
|
|
import { FileTimeService } from "@/file/time"
|
|
import { Instance } from "@/project/instance"
|
|
|
|
export { InstanceContext } from "./instance-context"
|
|
|
|
export type InstanceServices =
|
|
| QuestionService
|
|
| PermissionService
|
|
| ProviderAuthService
|
|
| FileWatcherService
|
|
| VcsService
|
|
| FileTimeService
|
|
|
|
function lookup(directory: string) {
|
|
const project = Instance.project
|
|
const ctx = Layer.sync(InstanceContext, () => InstanceContext.of({ directory, project }))
|
|
return Layer.mergeAll(
|
|
Layer.fresh(QuestionService.layer),
|
|
Layer.fresh(PermissionService.layer),
|
|
Layer.fresh(ProviderAuthService.layer),
|
|
Layer.fresh(FileWatcherService.layer).pipe(Layer.orDie),
|
|
Layer.fresh(VcsService.layer),
|
|
Layer.fresh(FileTimeService.layer).pipe(Layer.orDie),
|
|
).pipe(Layer.provide(ctx))
|
|
}
|
|
|
|
export class Instances extends ServiceMap.Service<Instances, LayerMap.LayerMap<string, InstanceServices>>()(
|
|
"opencode/Instances",
|
|
) {
|
|
static readonly layer = Layer.effect(
|
|
Instances,
|
|
Effect.gen(function* () {
|
|
const layerMap = yield* LayerMap.make(lookup, { idleTimeToLive: Infinity })
|
|
const unregister = registerDisposer((directory) => Effect.runPromise(layerMap.invalidate(directory)))
|
|
yield* Effect.addFinalizer(() => Effect.sync(unregister))
|
|
return Instances.of(layerMap)
|
|
}),
|
|
)
|
|
|
|
static get(directory: string): Layer.Layer<InstanceServices, never, Instances> {
|
|
return Layer.unwrap(Instances.use((map) => Effect.succeed(map.get(directory))))
|
|
}
|
|
|
|
static invalidate(directory: string): Effect.Effect<void, never, Instances> {
|
|
return Instances.use((map) => map.invalidate(directory))
|
|
}
|
|
}
|