summaryrefslogtreecommitdiffhomepage
path: root/js/src/app/app.ts
diff options
context:
space:
mode:
authorDax Raad <[email protected]>2025-05-29 11:58:40 -0400
committerDax Raad <[email protected]>2025-05-29 11:58:40 -0400
commit80597cd3fdf149cef87db55f03a3cc0bfd723a7a (patch)
treeb9332733cca2084a86334eb88fdc5115ab37b922 /js/src/app/app.ts
parent48f81fe4d3a286ead827888e030f9bd89c864dee (diff)
downloadopencode-80597cd3fdf149cef87db55f03a3cc0bfd723a7a.tar.gz
opencode-80597cd3fdf149cef87db55f03a3cc0bfd723a7a.zip
type error fix
Diffstat (limited to 'js/src/app/app.ts')
-rw-r--r--js/src/app/app.ts78
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;
+ });
+ }
+}