summaryrefslogtreecommitdiffhomepage
path: root/js/src/app/index.ts
blob: d8895098574818a30fc02e7129c67327f180cda3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import fs from "fs/promises";
import { AppPath } from "./path";
import { Log } from "../util/log";
import { Context } from "../util/context";
import { Config } from "./config";

export namespace App {
  const log = Log.create({ service: "app" });

  export type Info = Awaited<ReturnType<typeof create>>;

  const ctx = Context.create<Info>("app");

  export async function create(input: { directory: string }) {
    // Log.file(input.directory);
    log.info("creating");

    const config = await Config.load(input.directory);

    const dataDir = AppPath.data(input.directory);
    await fs.mkdir(dataDir, { recursive: true });
    log.info("created", { path: dataDir });

    const services = new Map<any, any>();

    const result = {
      get services() {
        return services;
      },
      get config() {
        return config;
      },
      get root() {
        return input.directory;
      },
      service<T extends (app: any) => any>(service: any, init: T) {},
    };

    return result;
  }

  export function state<T extends (app: Info) => any>(key: any, init: T) {
    return () => {
      const app = ctx.use();
      const services = app.services;
      if (!services.has(key)) {
        log.info("registering service", { name: key });
        services.set(key, init(app));
      }
      return services.get(key) as ReturnType<T>;
    };
  }

  export async function use() {
    return ctx.use();
  }

  export const provide = ctx.provide;
}