diff options
| author | Dax Raad <[email protected]> | 2025-05-29 11:58:40 -0400 |
|---|---|---|
| committer | Dax Raad <[email protected]> | 2025-05-29 11:58:40 -0400 |
| commit | 80597cd3fdf149cef87db55f03a3cc0bfd723a7a (patch) | |
| tree | b9332733cca2084a86334eb88fdc5115ab37b922 /js/src/app/app.ts | |
| parent | 48f81fe4d3a286ead827888e030f9bd89c864dee (diff) | |
| download | opencode-80597cd3fdf149cef87db55f03a3cc0bfd723a7a.tar.gz opencode-80597cd3fdf149cef87db55f03a3cc0bfd723a7a.zip | |
type error fix
Diffstat (limited to 'js/src/app/app.ts')
| -rw-r--r-- | js/src/app/app.ts | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/js/src/app/app.ts b/js/src/app/app.ts new file mode 100644 index 000000000..0c6260bc7 --- /dev/null +++ b/js/src/app/app.ts @@ -0,0 +1,78 @@ +import fs from "fs/promises"; +import { AppPath } from "./path"; +import { Log } from "../util/log"; +import { Context } from "../util/context"; + +export namespace App { + const log = Log.create({ service: "app" }); + + export type Info = Awaited<ReturnType<typeof create>>; + + const ctx = Context.create<Info>("app"); + + async function create(input: { directory: string }) { + const dataDir = AppPath.data(input.directory); + await fs.mkdir(dataDir, { recursive: true }); + await Log.file(input.directory); + + log.info("created", { path: dataDir }); + + const services = new Map< + any, + { + state: any; + shutdown?: (input: any) => Promise<void>; + } + >(); + + const result = { + get services() { + return services; + }, + get root() { + return input.directory; + }, + }; + + return result; + } + + export function state<State>( + key: any, + init: (app: Info) => State, + shutdown?: (state: Awaited<State>) => Promise<void>, + ) { + return () => { + const app = ctx.use(); + const services = app.services; + if (!services.has(key)) { + log.info("registering service", { name: key }); + services.set(key, { + state: init(app), + shutdown: shutdown, + }); + } + return services.get(key)?.state as State; + }; + } + + export async function use() { + return ctx.use(); + } + + export async function provide<T extends (app: Info) => any>( + input: { directory: string }, + cb: T, + ) { + const app = await create(input); + + return ctx.provide(app, async () => { + const result = await cb(app); + for (const [key, entry] of app.services.entries()) { + log.info("shutdown", { name: key }); + await entry.shutdown?.(await entry.state); + } + return result; + }); + } +} |
