main.ts

2.2 KB · raw

1import { join } from "node:path";2import type { Hono } from "hono";3import { createSetupApp } from "./admin/setup.ts";4import { startStorageLoop } from "./admin/storage.ts";5import { openBucket } from "./bucket/reader.ts";6import { startSyncWorker } from "./bucket/sync.ts";7import { openMirrors } from "./mirror/store.ts";8import { createApp } from "./server/app.ts";9import { startBackupLoop } from "./server/backup.ts";10import { CONFIG_FILE, type Config, ConfigError, loadConfig } from "./server/config.ts";11import { oneTimeCode } from "./server/connect.ts";12import { openKeprDb } from "./server/db.ts";13import { startMailLoop } from "./server/mail.ts";1415// Where a first-run setup puts Kepr's data, beside kepr.toml.16const DATA_DIR = "data";1718/** Starts the loops for a config and returns the app that serves it. */19function start(config: Config): Hono["fetch"] {20	const kepr = openKeprDb(config.dataDir);21	// One bucket for the sync loop and the app, so settings saved in the console reach both.22	const bucket = openBucket(config.bucket);23	startBackupLoop(kepr, config);24	startMailLoop(kepr, config);25	const mirrorDir = join(config.dataDir, "mirror");26	openMirrors(mirrorDir);27	// The first visitor after a new save would otherwise wait a second or two on a big repo.28	const syncer = startSyncWorker(config.dataDir, config.bucket);29	startStorageLoop({ bucket, kepr, mirrorDir });30	return createApp(config, kepr, bucket, CONFIG_FILE, syncer).fetch;31}3233try {34	let fetch: Hono["fetch"];35	if (await Bun.file(CONFIG_FILE).exists()) {36		fetch = start(await loadConfig(CONFIG_FILE));37	} else {38		const code = oneTimeCode();39		fetch = createSetupApp({40			code,41			configPath: CONFIG_FILE,42			dataDir: DATA_DIR,43			done: (config) => {44				fetch = start(config);45			},46		}).fetch;47		console.log(48			`kepr: no ${CONFIG_FILE} yet. Open /setup in a browser and enter the code ${code.slice(0, 4)}-${code.slice(4)}`,49		);50	}51	// Bun.serve reads the port from $PORT (default 3000).52	const server = Bun.serve({ fetch: (request, bun) => fetch(request, bun) });53	console.log(`kepr listening on ${server.url}`);54} catch (error) {55	if (!(error instanceof ConfigError)) throw error;56	console.error(`kepr: ${error.message}`);57	process.exit(1);58}