Initial Commit

This commit is contained in:
2026-08-08 22:23:27 +07:00 Unverified
commit c08fb36d2e
22 changed files with 6212 additions and 0 deletions
+50
View File
@@ -0,0 +1,50 @@
import { AsyncLocalStorage } from "node:async_hooks";
import type { ComposeSpecification } from "../schema/docker.d";
import { getProject, throwWhen } from "./shared";
import { readCompose, resolveComposeFile } from "./yaml";
type AppContext = {
project: string;
cwd: string;
path(): Promise<string | undefined>;
compose(): Promise<ComposeSpecification>;
};
const appContext = new AsyncLocalStorage<AppContext>();
export function provideContext<T>(fn: () => T): T {
const cwd = process.cwd();
const path = createCachedGetter("composeFile", () => resolveComposeFile(cwd));
return appContext.run(
{
project: getProject(),
cwd,
path,
compose: createCachedGetter("compose", () =>
path()
.then(throwWhen((path): path is undefined => path === undefined))
.then(readCompose),
),
},
fn,
);
}
export function ctx() {
const store = appContext.getStore();
if (!store) throw new Error("Not in context!");
return store;
}
const cache: Record<string, unknown> = {};
export function createCachedGetter<T>(
key: string,
fn: () => Promise<T>,
): () => Promise<T> {
return async () => {
if (key in cache) return cache[key] as T;
const result = await fn();
cache[key] = result;
return result;
};
}