mirror of
https://gitea.toothfairyai.com/ToothFairyAI/tf_code.git
synced 2026-03-30 05:43:55 +00:00
69 lines
1.9 KiB
TypeScript
69 lines
1.9 KiB
TypeScript
import { Log } from "@/util/log"
|
|
import { Context } from "../util/context"
|
|
import { Project } from "./project"
|
|
import { State } from "./state"
|
|
import { iife } from "@/util/iife"
|
|
|
|
interface Context {
|
|
directory: string
|
|
worktree: string
|
|
project: Project.Info
|
|
}
|
|
const context = Context.create<Context>("instance")
|
|
const cache = new Map<string, Promise<Context>>()
|
|
|
|
export const Instance = {
|
|
async provide<R>(input: { directory: string; init?: () => Promise<any>; fn: () => R }): Promise<R> {
|
|
let existing = cache.get(input.directory)
|
|
if (!existing) {
|
|
Log.Default.info("creating instance", { directory: input.directory })
|
|
existing = iife(async () => {
|
|
const project = await Project.fromDirectory(input.directory)
|
|
const ctx = {
|
|
directory: input.directory,
|
|
worktree: project.worktree,
|
|
project,
|
|
}
|
|
await context.provide(ctx, async () => {
|
|
await input.init?.()
|
|
})
|
|
return ctx
|
|
})
|
|
cache.set(input.directory, existing)
|
|
}
|
|
const ctx = await existing
|
|
return context.provide(ctx, async () => {
|
|
return input.fn()
|
|
})
|
|
},
|
|
get directory() {
|
|
return context.use().directory
|
|
},
|
|
get worktree() {
|
|
return context.use().worktree
|
|
},
|
|
get project() {
|
|
return context.use().project
|
|
},
|
|
state<S>(init: () => S, dispose?: (state: Awaited<S>) => Promise<void>): () => S {
|
|
return State.create(() => Instance.directory, init, dispose)
|
|
},
|
|
async dispose() {
|
|
Log.Default.info("disposing instance", { directory: Instance.directory })
|
|
await State.dispose(Instance.directory)
|
|
cache.delete(Instance.directory)
|
|
},
|
|
async disposeAll() {
|
|
Log.Default.info("disposing all instances")
|
|
for (const [_key, value] of cache) {
|
|
const awaited = await value.catch(() => {})
|
|
if (awaited) {
|
|
await context.provide(await value, async () => {
|
|
await Instance.dispose()
|
|
})
|
|
}
|
|
}
|
|
cache.clear()
|
|
},
|
|
}
|