mirror of
https://gitea.toothfairyai.com/ToothFairyAI/tf_code.git
synced 2026-03-31 06:12:26 +00:00
66 lines
1.7 KiB
TypeScript
66 lines
1.7 KiB
TypeScript
import { Log } from "@/util/log"
|
|
|
|
export namespace State {
|
|
interface Entry {
|
|
state: any
|
|
dispose?: (state: any) => Promise<void>
|
|
}
|
|
|
|
const log = Log.create({ service: "state" })
|
|
const recordsByKey = new Map<string, Map<any, Entry>>()
|
|
|
|
export function create<S>(root: () => string, init: () => S, dispose?: (state: Awaited<S>) => Promise<void>) {
|
|
return () => {
|
|
const key = root()
|
|
let entries = recordsByKey.get(key)
|
|
if (!entries) {
|
|
entries = new Map<string, Entry>()
|
|
recordsByKey.set(key, entries)
|
|
}
|
|
const exists = entries.get(init)
|
|
if (exists) return exists.state as S
|
|
const state = init()
|
|
entries.set(init, {
|
|
state,
|
|
dispose,
|
|
})
|
|
return state
|
|
}
|
|
}
|
|
|
|
export async function dispose(key: string) {
|
|
const entries = recordsByKey.get(key)
|
|
if (!entries) return
|
|
|
|
log.info("waiting for state disposal to complete", { key })
|
|
|
|
let disposalFinished = false
|
|
|
|
setTimeout(() => {
|
|
if (!disposalFinished) {
|
|
log.warn(
|
|
"state disposal is taking an unusually long time - if it does not complete in a reasonable time, please report this as a bug",
|
|
{ key },
|
|
)
|
|
}
|
|
}, 10000).unref()
|
|
|
|
const tasks: Promise<void>[] = []
|
|
for (const entry of entries.values()) {
|
|
if (!entry.dispose) continue
|
|
|
|
const task = Promise.resolve(entry.state)
|
|
.then((state) => entry.dispose!(state))
|
|
.catch((error) => {
|
|
log.error("Error while disposing state:", { error, key })
|
|
})
|
|
|
|
tasks.push(task)
|
|
}
|
|
entries.clear()
|
|
await Promise.all(tasks)
|
|
disposalFinished = true
|
|
log.info("state disposal completed", { key })
|
|
}
|
|
}
|