Skip to content

Instantly share code, notes, and snippets.

@JonDotsoy
Last active May 6, 2024 02:40
Show Gist options
  • Save JonDotsoy/23d928b0d05f74bd35c01e636d48ad2f to your computer and use it in GitHub Desktop.
Save JonDotsoy/23d928b0d05f74bd35c01e636d48ad2f to your computer and use it in GitHub Desktop.
import { z } from "zod";
import * as fs from "fs/promise";
export class LifeConfig<T extends z.ZodObject<any>> {
bootstrapProcess: Promise<void>;
watchingProcess: null | Promise<void> = null;
store: null | z.infer<T> = null;
ready = Promise.withResolvers<null>();
subs = new Set<(state: z.infer<T>) => void>();
constructor(
private file: string | { toString(): string },
private schema: T,
) {
this.bootstrapProcess = this.bootstrap();
}
async bootstrap() {
await this.load();
this.watchingProcess = this.startWatchFile();
}
async startWatchFile() {
for await (const event of fs.watch(new URL(`${this.file}`).pathname)) {
await this.load();
}
}
async load() {
const store = this.schema.parse(
JSON.parse(await fs.readFile(new URL(`${this.file}`), "utf-8")),
);
this.store = store;
this.subs.forEach((cb) => cb(store));
this.ready.resolve(null);
}
async wait() {
await this.bootstrapProcess;
await this.ready.promise;
}
async setup(cb: (state: z.infer<T>) => void) {
if (this.store) cb(this.store);
this.subs.add(cb);
return () => this.subs.delete(cb);
}
}
import { z } from "zod";
import { LifeConfig } from "./life-config.ts"
const lifeConfig = new LifeConfig(
"config.json",
z.object({
prefixLog: z.string(),
}),
);
await lifeConfig.wait();
let logger = (message: string) => comsole.log(`${lifeConfig.store.prefixLog} ${message}`);
lifeConfig.setup(() => {
logger = (message: string) => comsole.log(`${lifeConfig.store.prefixLog} ${message}`);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment