flightdeck 0.4.14 → 0.4.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,9 +3,9 @@ import { createServer } from "node:http";
3
3
  import { homedir } from "node:os";
4
4
  import { resolve } from "node:path";
5
5
  import { inspect } from "node:util";
6
- import { Future } from "atom.io/internal";
6
+ import { fromEntries, toEntries } from "atom.io/foundations/entries";
7
+ import { Future } from "atom.io/foundations/future";
7
8
  import { discoverType } from "atom.io/introspection";
8
- import { fromEntries, toEntries } from "atom.io/json";
9
9
  import { ChildSocket } from "atom.io/realtime-server";
10
10
  import { CronJob } from "cron";
11
11
  import { FilesystemStorage } from "safedeposit";
@@ -440,4 +440,4 @@ var FlightDeckLogger = class {
440
440
  //#endregion
441
441
  export { FLIGHTDECK_UPDATE_PHASES as a, FlightDeckLogger as c, FLIGHTDECK_SETUP_PHASES as i, isVersionNumber as l, FLIGHTDECK_INFO as n, FLIGHTDECK_WARN as o, FLIGHTDECK_LNAV_FORMAT as r, FlightDeck as s, FLIGHTDECK_ERROR as t };
442
442
 
443
- //# sourceMappingURL=flightdeck.lib-Dfs4xGO7.js.map
443
+ //# sourceMappingURL=flightdeck.lib-D19FU1Vu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flightdeck.lib-D19FU1Vu.js","names":[],"sources":["../src/flightdeck.env.ts","../src/flightdeck.lib.ts"],"sourcesContent":["import { createEnv } from \"@t3-oss/env-core\"\nimport { type } from \"arktype\"\n\nexport const env = createEnv({\n\tserver: { FLIGHTDECK_SECRET: type(`string`, `|`, `undefined`) },\n\tclientPrefix: `NEVER`,\n\tclient: {},\n\truntimeEnv: import.meta.env,\n\temptyStringAsUndefined: true,\n})\n","/* oxlint-disable typescript/only-throw-error */\nimport type { ChildProcessWithoutNullStreams } from \"node:child_process\"\nimport { execSync, spawn } from \"node:child_process\"\nimport { createServer } from \"node:http\"\nimport { homedir } from \"node:os\"\nimport { resolve } from \"node:path\"\nimport { inspect } from \"node:util\"\n\nimport { fromEntries, toEntries } from \"atom.io/foundations/entries\"\nimport { Future } from \"atom.io/foundations/future\"\nimport { discoverType } from \"atom.io/introspection\"\nimport { ChildSocket } from \"atom.io/realtime-server\"\nimport { CronJob } from \"cron\"\nimport { FilesystemStorage } from \"safedeposit\"\n\nimport type { LnavFormat } from \"../gen/lnav-format-schema.gen.ts\"\nimport { env } from \"./flightdeck.env.ts\"\n\nexport const FLIGHTDECK_SETUP_PHASES = [`downloaded`, `installed`] as const\n\nexport type FlightDeckSetupPhase = (typeof FLIGHTDECK_SETUP_PHASES)[number]\n\nexport const FLIGHTDECK_UPDATE_PHASES = [`notified`, `confirmed`] as const\n\nexport type FlightDeckUpdatePhase = (typeof FLIGHTDECK_UPDATE_PHASES)[number]\n\nexport function isVersionNumber(version: string): boolean {\n\treturn (\n\t\t/^\\d+\\.\\d+\\.\\d+$/.test(version) || !Number.isNaN(Number.parseFloat(version))\n\t)\n}\n\nexport type FlightDeckSaveData = {\n\tcurrentPid: `${number}`\n\tsetupPhase: FlightDeckSetupPhase\n\tupdatePhase: FlightDeckUpdatePhase\n\tupdateAwaitedVersion: string\n}\n\nexport type FlightDeckOptions<S extends string = string> = {\n\treadonly packageName: string\n\treadonly services: { [service in S]: { run: string; waitFor: boolean } }\n\treadonly scripts: {\n\t\treadonly download: string\n\t\treadonly install: string\n\t\treadonly checkAvailability?: string\n\t}\n\treadonly port?: number | undefined\n\treadonly flightdeckRootDir?: string | undefined\n\treadonly jsonLogging?: boolean | undefined\n}\n\nasync function waitForPidExit(pid: number, timeoutMs = 5000, intervalMs = 100) {\n\treturn new Promise<void>((pass, fail) => {\n\t\tconst start = Date.now()\n\n\t\tconst check = () => {\n\t\t\tprocess.stdout.write(`.`)\n\t\t\ttry {\n\t\t\t\t// check existence\n\t\t\t\tprocess.kill(pid, 0)\n\t\t\t\t// process still alive\n\t\t\t\tif (Date.now() - start > timeoutMs) {\n\t\t\t\t\tfail(new Error(`Timeout waiting for PID ${pid}`))\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tsetTimeout(check, intervalMs)\n\t\t\t} catch (err) {\n\t\t\t\tif (err instanceof Error && `code` in err) {\n\t\t\t\t\tif (err.code === `ESRCH`) {\n\t\t\t\t\t\tpass()\n\t\t\t\t\t\treturn // exited\n\t\t\t\t\t}\n\t\t\t\t\tif (err.code === `EPERM`) {\n\t\t\t\t\t\t// process is alive but protected\n\t\t\t\t\t\tif (Date.now() - start > timeoutMs) {\n\t\t\t\t\t\t\tfail(\n\t\t\t\t\t\t\t\tnew Error(`Timeout waiting for PID ${pid} (EPERM; still alive)`),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn setTimeout(check, intervalMs)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfail(err)\n\t\t\t\treturn // unexpected error\n\t\t\t}\n\t\t}\n\n\t\tcheck()\n\t})\n}\n\nexport class FlightDeck<S extends string = string> {\n\tpublic static async kill(\n\t\tflightdeckRootDir: string,\n\t\tpackageName: string,\n\t): Promise<number> {\n\t\tconsole.info(`Killing FlightDeck instance of \"${packageName}\"`)\n\t\tconst storage = new FilesystemStorage<FlightDeckSaveData>({\n\t\t\tpath: resolve(flightdeckRootDir, `storage`, packageName),\n\t\t})\n\t\tconst currentPid = storage.getItem(`currentPid`)\n\t\tif (currentPid === null) {\n\t\t\tthrow new Error(`No pid for \"${packageName}\" found in storage`)\n\t\t}\n\t\tconst pid = Number(currentPid)\n\t\tconst now = Date.now()\n\t\tprocess.kill(pid, `SIGTERM`)\n\t\tawait waitForPidExit(pid, 5000, 5)\n\t\tconst elapsed = Date.now() - now\n\t\tprocess.stdout.write(\n\t\t\t`🌜 \"${packageName}\" (running as process ${pid}) exited in ${elapsed}ms\\n`,\n\t\t)\n\t\treturn pid\n\t}\n\n\tpublic readonly options: FlightDeckOptions<S>\n\tprotected safety = 0\n\n\tprotected storage: FilesystemStorage<FlightDeckSaveData>\n\tprotected services: {\n\t\t[service in S]: ChildSocket<\n\t\t\t{ timeToStop: []; updatesReady: [] },\n\t\t\t{ readyToUpdate: []; alive: [] },\n\t\t\tChildProcessWithoutNullStreams\n\t\t> | null\n\t}\n\tprotected serviceIdx: { readonly [service in S]: number }\n\tpublic defaultServicesReadyToUpdate: { readonly [service in S]: boolean }\n\tpublic servicesReadyToUpdate: { [service in S]: boolean }\n\tpublic autoRespawnDeadServices: boolean\n\n\tprotected logger: Pick<Console, `error` | `info` | `warn`>\n\tprotected serviceLoggers: {\n\t\treadonly [service in S]: FlightDeckLogger\n\t}\n\n\tprotected updateAvailabilityChecker: CronJob | null = null\n\n\tpublic servicesLive: Future<void>[]\n\tpublic servicesDead: Future<void>[]\n\tpublic live = new Future(() => {})\n\tpublic dead = new Future(() => {})\n\n\tprotected restartTimes: number[] = []\n\n\tpublic constructor(options: FlightDeckOptions<S>) {\n\t\tthis.options = options\n\t\tconst { FLIGHTDECK_SECRET } = env\n\t\tconst { flightdeckRootDir = resolve(homedir(), `.flightdeck`) } = options\n\t\tconst port = options.port ?? 8080\n\t\tconst origin = `http://localhost:${port}`\n\n\t\tconst servicesEntries = toEntries(options.services)\n\t\tthis.services = fromEntries(\n\t\t\tservicesEntries.map(([serviceName]) => [serviceName, null]),\n\t\t)\n\t\tthis.serviceIdx = fromEntries(\n\t\t\tservicesEntries.map(([serviceName], idx) => [serviceName, idx]),\n\t\t)\n\t\tthis.defaultServicesReadyToUpdate = fromEntries(\n\t\t\tservicesEntries.map(([serviceName, { waitFor }]) => [\n\t\t\t\tserviceName,\n\t\t\t\t!waitFor,\n\t\t\t]),\n\t\t)\n\t\tthis.servicesReadyToUpdate = { ...this.defaultServicesReadyToUpdate }\n\t\tthis.autoRespawnDeadServices = true\n\n\t\tthis.logger = new FlightDeckLogger(\n\t\t\tthis.options.packageName,\n\t\t\tprocess.pid,\n\t\t\tundefined,\n\t\t\t{ jsonLogging: this.options.jsonLogging ?? false },\n\t\t)\n\t\tthis.serviceLoggers = fromEntries(\n\t\t\tservicesEntries.map(([serviceName]) => [\n\t\t\t\tserviceName,\n\t\t\t\tnew FlightDeckLogger(\n\t\t\t\t\tthis.options.packageName,\n\t\t\t\t\tprocess.pid,\n\t\t\t\t\tserviceName,\n\t\t\t\t\t{ jsonLogging: this.options.jsonLogging ?? false },\n\t\t\t\t),\n\t\t\t]),\n\t\t)\n\n\t\tthis.servicesLive = servicesEntries.map(() => new Future(() => {}))\n\t\tthis.servicesDead = servicesEntries.map(() => new Future(() => {}))\n\t\tthis.live.use(Promise.all(this.servicesLive))\n\t\tthis.dead.use(Promise.all(this.servicesDead))\n\n\t\tthis.storage = new FilesystemStorage({\n\t\t\tpath: resolve(flightdeckRootDir, `storage`, options.packageName),\n\t\t})\n\n\t\tthis.storage.setItem(`currentPid`, `${process.pid}`)\n\n\t\tif (FLIGHTDECK_SECRET === undefined) {\n\t\t\tthis.logger.warn(\n\t\t\t\t`No FLIGHTDECK_SECRET environment variable found. FlightDeck will not run an update server.`,\n\t\t\t)\n\t\t} else {\n\t\t\tcreateServer((req, res) => {\n\t\t\t\tlet data: Uint8Array[] = []\n\t\t\t\treq\n\t\t\t\t\t.on(`data`, (chunk) => {\n\t\t\t\t\t\tdata.push(chunk instanceof Buffer ? chunk : Buffer.from(chunk))\n\t\t\t\t\t})\n\t\t\t\t\t.on(`end`, async () => {\n\t\t\t\t\t\tconst authHeader = req.headers.authorization\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tif (typeof req.url === `undefined`) throw 400\n\t\t\t\t\t\t\tconst expectedAuthHeader = `Bearer ${FLIGHTDECK_SECRET}`\n\t\t\t\t\t\t\tif (authHeader !== `Bearer ${FLIGHTDECK_SECRET}`) {\n\t\t\t\t\t\t\t\tthis.logger.info(\n\t\t\t\t\t\t\t\t\t`Unauthorized: needed \\`${expectedAuthHeader}\\`, got \\`${authHeader}\\``,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\tthrow 401\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst url = new URL(req.url, origin)\n\t\t\t\t\t\t\tthis.logger.info(req.method, url.pathname)\n\n\t\t\t\t\t\t\tconst versionForeignInput = Buffer.concat(data).toString()\n\t\t\t\t\t\t\tif (!isVersionNumber(versionForeignInput)) {\n\t\t\t\t\t\t\t\tthrow 400\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tres.writeHead(200)\n\t\t\t\t\t\t\tres.end()\n\n\t\t\t\t\t\t\tthis.storage.setItem(`updatePhase`, `notified`)\n\t\t\t\t\t\t\tthis.storage.setItem(`updateAwaitedVersion`, versionForeignInput)\n\t\t\t\t\t\t\tconst { checkAvailability } = options.scripts\n\t\t\t\t\t\t\tif (checkAvailability) {\n\t\t\t\t\t\t\t\tawait this.updateAvailabilityChecker?.stop()\n\t\t\t\t\t\t\t\tawait this.seekUpdate(versionForeignInput)\n\t\t\t\t\t\t\t\tconst updatePhase = this.storage.getItem(`updatePhase`)\n\t\t\t\t\t\t\t\tthis.logger.info(`> storage(\"updatePhase\") >`, updatePhase)\n\t\t\t\t\t\t\t\tif (updatePhase === `notified`) {\n\t\t\t\t\t\t\t\t\tthis.updateAvailabilityChecker = new CronJob(\n\t\t\t\t\t\t\t\t\t\t`*/30 * * * * *`,\n\t\t\t\t\t\t\t\t\t\tasync () => {\n\t\t\t\t\t\t\t\t\t\t\tawait this.seekUpdate(versionForeignInput)\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\tthis.updateAvailabilityChecker.start()\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.downloadPackage()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch (thrown) {\n\t\t\t\t\t\t\tthis.logger.error(thrown, req.url)\n\t\t\t\t\t\t\tif (typeof thrown === `number`) {\n\t\t\t\t\t\t\t\tres.writeHead(thrown)\n\t\t\t\t\t\t\t\tres.end()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} finally {\n\t\t\t\t\t\t\tdata = []\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t}).listen(port, () => {\n\t\t\t\tthis.logger.info(`Server started on port ${port}`)\n\t\t\t})\n\t\t}\n\n\t\tthis.startAllServices()\n\t\t\t.then(() => {\n\t\t\t\tthis.logger.info(`All services started.`)\n\t\t\t})\n\t\t\t.catch((thrown) => {\n\t\t\t\tif (thrown instanceof Error) {\n\t\t\t\t\tthis.logger.error(`Failed to start all services:`, thrown.message)\n\t\t\t\t}\n\t\t\t})\n\n\t\tprocess.on(`SIGTERM`, async () => {\n\t\t\tconsole.info(`Killed by SIGTERM`)\n\t\t\tawait this.stopAllServices()\n\t\t\tthis.storage.removeItem(`currentPid`)\n\t\t\tprocess.exit(0)\n\t\t})\n\t}\n\n\tprotected async seekUpdate(version: string): Promise<void> {\n\t\tthis.logger.info(`Checking for updates...`)\n\t\tconst { checkAvailability } = this.options.scripts\n\t\tif (!checkAvailability) {\n\t\t\tthis.logger.info(`No checkAvailability script found.`)\n\t\t\treturn\n\t\t}\n\t\ttry {\n\t\t\tconst out = execSync(`${checkAvailability} ${version}`)\n\t\t\tthis.logger.info(`Check stdout:`, out.toString())\n\t\t\tawait this.updateAvailabilityChecker?.stop()\n\t\t\tthis.storage.setItem(`updatePhase`, `confirmed`)\n\t\t\tthis.downloadPackage()\n\t\t\tthis.announceUpdate()\n\t\t} catch (thrown) {\n\t\t\tif (thrown instanceof Error) {\n\t\t\t\tthis.logger.error(`Check failed:`, thrown.message)\n\t\t\t} else {\n\t\t\t\tconst thrownType = discoverType(thrown)\n\t\t\t\tthis.logger.error(`Check threw`, thrownType, thrown)\n\t\t\t}\n\t\t}\n\t}\n\n\tprotected announceUpdate(): void {\n\t\tfor (const entry of toEntries(this.services)) {\n\t\t\tconst [serviceName, service] = entry\n\t\t\tif (service) {\n\t\t\t\tif (this.options.services[serviceName].waitFor) {\n\t\t\t\t\tservice.emit(`updatesReady`)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis.startService(serviceName)\n\t\t\t}\n\t\t}\n\t}\n\n\tprotected tryUpdate(): void {\n\t\tif (toEntries(this.servicesReadyToUpdate).every(([, isReady]) => isReady)) {\n\t\t\tthis.logger.info(`All services are ready to update.`)\n\t\t\tthis.stopAllServices()\n\t\t\t\t.then(() => {\n\t\t\t\t\tthis.logger.info(`All services stopped; starting up fresh...`)\n\t\t\t\t\tthis.startAllServices()\n\t\t\t\t\t\t.then(() => {\n\t\t\t\t\t\t\tthis.logger.info(`All services started; we're back online.`)\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.catch((thrown) => {\n\t\t\t\t\t\t\tif (thrown instanceof Error) {\n\t\t\t\t\t\t\t\tthis.logger.error(\n\t\t\t\t\t\t\t\t\t`Failed to start all services:`,\n\t\t\t\t\t\t\t\t\tthrown.message,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t\t.catch((thrown) => {\n\t\t\t\t\tif (thrown instanceof Error) {\n\t\t\t\t\t\tthis.logger.error(`Failed to stop all services:`, thrown.message)\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t}\n\t}\n\n\tprotected startAllServices(): Future<unknown> {\n\t\tthis.logger.info(`Starting all services...`)\n\t\tthis.autoRespawnDeadServices = true\n\t\tconst setupPhase = this.storage.getItem(`setupPhase`)\n\t\tthis.logger.info(`> storage(\"setupPhase\") >`, setupPhase)\n\t\tswitch (setupPhase) {\n\t\t\tcase null:\n\t\t\t\tthis.logger.info(`Starting from scratch.`)\n\t\t\t\tthis.downloadPackage()\n\t\t\t\tthis.installPackage()\n\t\t\t\treturn this.startAllServices()\n\t\t\tcase `downloaded`:\n\t\t\t\tthis.logger.info(`Found package downloaded but not installed.`)\n\t\t\t\tthis.installPackage()\n\t\t\t\treturn this.startAllServices()\n\t\t\tcase `installed`: {\n\t\t\t\tfor (const [serviceName] of toEntries(this.services)) {\n\t\t\t\t\tthis.startService(serviceName)\n\t\t\t\t}\n\t\t\t\treturn this.live\n\t\t\t}\n\t\t}\n\t}\n\n\tprotected startService(serviceName: S): void {\n\t\tthis.logger.info(\n\t\t\t`Starting service ${this.options.packageName}::${serviceName}, try ${this.safety}/2...`,\n\t\t)\n\t\tif (this.safety >= 2) {\n\t\t\tthrow new Error(`Out of tries...`)\n\t\t}\n\t\tthis.safety++\n\n\t\tconst [exe, ...args] = this.options.services[serviceName].run.split(` `)\n\t\tconst serviceProcess = spawn(exe, args, {\n\t\t\tcwd: this.options.flightdeckRootDir,\n\t\t\tenv: import.meta.env,\n\t\t})\n\t\tconst serviceLogger = this.serviceLoggers[serviceName]\n\t\tconst service = (this.services[serviceName] = new ChildSocket(\n\t\t\tserviceProcess,\n\t\t\t`${this.options.packageName}::${serviceName}`,\n\t\t\tserviceLogger,\n\t\t))\n\t\tserviceLogger.processCode = service.proc.pid ?? -1\n\t\tthis.services[serviceName].onAny((...messages) => {\n\t\t\tserviceLogger.info(`💬`, ...messages)\n\t\t})\n\t\tthis.services[serviceName].on(`readyToUpdate`, () => {\n\t\t\tthis.logger.info(`Service \"${serviceName}\" is ready to update.`)\n\t\t\tthis.servicesReadyToUpdate[serviceName] = true\n\t\t\tthis.tryUpdate()\n\t\t})\n\t\tthis.services[serviceName].on(`alive`, () => {\n\t\t\tthis.servicesLive[this.serviceIdx[serviceName]].use(Promise.resolve())\n\t\t\tthis.servicesDead[this.serviceIdx[serviceName]] = new Future(() => {})\n\t\t\tif (this.dead.done) {\n\t\t\t\tthis.dead = new Future(() => {})\n\t\t\t}\n\t\t\tthis.dead.use(Promise.all(this.servicesDead))\n\t\t})\n\t\tthis.services[serviceName].proc.once(`close`, (exitCode) => {\n\t\t\tthis.logger.info(\n\t\t\t\t`Auto-respawn saw \"${serviceName}\" exit with code ${exitCode}`,\n\t\t\t)\n\t\t\tthis.services[serviceName] = null\n\t\t\tif (!this.autoRespawnDeadServices) {\n\t\t\t\tthis.logger.info(`😴 Auto-respawn is off; \"${serviceName}\" rests.`)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst updatePhase = this.storage.getItem(`updatePhase`)\n\t\t\tthis.logger.info(`> storage(\"updatePhase\") >`, updatePhase)\n\t\t\tconst updatesAreReady = updatePhase === `confirmed`\n\t\t\tif (updatesAreReady) {\n\t\t\t\tthis.serviceLoggers[serviceName].info(`Updating before startup...`)\n\t\t\t\tthis.restartTimes = []\n\t\t\t\tthis.installPackage()\n\t\t\t\tthis.startService(serviceName)\n\t\t\t} else {\n\t\t\t\tconst now = Date.now()\n\t\t\t\tconst fiveMinutesAgo = now - 5 * 60 * 1000\n\t\t\t\tthis.restartTimes = this.restartTimes.filter(\n\t\t\t\t\t(time) => time > fiveMinutesAgo,\n\t\t\t\t)\n\t\t\t\tthis.restartTimes.push(now)\n\n\t\t\t\tif (this.restartTimes.length < 5) {\n\t\t\t\t\tthis.serviceLoggers[serviceName].info(`Crashed. Restarting...`)\n\t\t\t\t\tthis.startService(serviceName)\n\t\t\t\t} else {\n\t\t\t\t\tthis.serviceLoggers[serviceName].info(\n\t\t\t\t\t\t`Crashed 5 times in 5 minutes. Not restarting.`,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t\tthis.safety = 0\n\t}\n\n\tprotected downloadPackage(): void {\n\t\tthis.logger.info(`Downloading...`)\n\t\ttry {\n\t\t\tconst out = execSync(this.options.scripts.download)\n\t\t\tthis.logger.info(`Download stdout:`, out.toString())\n\t\t\tthis.storage.setItem(`setupPhase`, `downloaded`)\n\t\t\tthis.logger.info(`Downloaded!`)\n\t\t} catch (thrown) {\n\t\t\tif (thrown instanceof Error) {\n\t\t\t\tthis.logger.error(`Failed to get the latest release: ${thrown.message}`)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t}\n\n\tprotected installPackage(): void {\n\t\tthis.logger.info(`Installing...`)\n\n\t\ttry {\n\t\t\tconst out = execSync(this.options.scripts.install)\n\t\t\tthis.logger.info(`Install stdout:`, out.toString())\n\t\t\tthis.storage.setItem(`setupPhase`, `installed`)\n\t\t\tthis.logger.info(`Installed!`)\n\t\t} catch (thrown) {\n\t\t\tif (thrown instanceof Error) {\n\t\t\t\tthis.logger.error(`Failed to get the latest release: ${thrown.message}`)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t}\n\n\tpublic stopAllServices(): Future<unknown> {\n\t\tthis.logger.info(`Stopping all services... auto-respawn disabled.`)\n\t\tthis.autoRespawnDeadServices = false\n\t\tfor (const [serviceName] of toEntries(this.services)) {\n\t\t\tthis.stopService(serviceName)\n\t\t}\n\t\treturn this.dead\n\t}\n\n\tpublic stopService(serviceName: S): void {\n\t\tconst service = this.services[serviceName]\n\t\tif (service) {\n\t\t\tthis.logger.info(`Stopping service \"${serviceName}\"...`)\n\t\t\tthis.servicesDead[this.serviceIdx[serviceName]].use(\n\t\t\t\tnew Promise((pass) => {\n\t\t\t\t\tservice.emit(`timeToStop`)\n\t\t\t\t\tservice.proc.once(`close`, (exitCode) => {\n\t\t\t\t\t\tthis.logger.info(\n\t\t\t\t\t\t\t`Stopped service \"${serviceName}\"; exited with code ${exitCode}`,\n\t\t\t\t\t\t)\n\t\t\t\t\t\tthis.services[serviceName] = null\n\t\t\t\t\t\tpass()\n\t\t\t\t\t})\n\t\t\t\t}),\n\t\t\t)\n\t\t\tthis.dead.use(Promise.all(this.servicesDead))\n\t\t\tthis.servicesLive[this.serviceIdx[serviceName]] = new Future(() => {})\n\t\t\tif (this.live.done) {\n\t\t\t\tthis.live = new Future(() => {})\n\t\t\t}\n\t\t\tthis.live.use(Promise.all(this.servicesLive))\n\t\t} else {\n\t\t\tthis.serviceLoggers[serviceName].error(\n\t\t\t\t`Tried to stop service, but it wasn't running.`,\n\t\t\t)\n\t\t}\n\t}\n}\n\nexport const FLIGHTDECK_INFO = `info`\nexport const FLIGHTDECK_WARN = `warn`\nexport const FLIGHTDECK_ERROR = `ERR!`\n\nexport type FlightDeckLog = {\n\tlevel:\n\t\t| typeof FLIGHTDECK_ERROR\n\t\t| typeof FLIGHTDECK_INFO\n\t\t| typeof FLIGHTDECK_WARN\n\ttimestamp: number\n\tpackage: string\n\tservice?: string\n\tprocess: number\n\tbody: string\n}\n\nconst LINE_FORMAT = `line-format` satisfies keyof LnavFormat\nconst VALUE = `value` satisfies keyof LnavFormat\n\nexport type LnavFormatVisualComponent = Exclude<\n\tExclude<LnavFormat[`line-format`], undefined>[number],\n\tstring\n>\n\nexport type LnavFormatBreakdown = Exclude<LnavFormat[`value`], undefined>\nexport type MemberOf<T> = T[keyof T]\nexport type LnavFormatValueDefinition = MemberOf<LnavFormatBreakdown>\n\nexport type FlightDeckFormat = {\n\t[LINE_FORMAT]: (\n\t\t| string\n\t\t| (LnavFormatVisualComponent & {\n\t\t\t\tfield: keyof FlightDeckLog | `__level__` | `__timestamp__`\n\t\t })\n\t)[]\n\t[VALUE]: {\n\t\t[K in keyof FlightDeckLog]: LnavFormatValueDefinition & {\n\t\t\tkind: FlightDeckLog[K] extends number | undefined\n\t\t\t\t? `integer`\n\t\t\t\t: FlightDeckLog[K] extends string | undefined\n\t\t\t\t\t? `string`\n\t\t\t\t\t: never\n\t\t}\n\t}\n}\n\nexport const FLIGHTDECK_LNAV_FORMAT = {\n\ttitle: `FlightDeck Log`,\n\tdescription: `Format for events logged by the FlightDeck process manager.`,\n\t\"file-type\": `json`,\n\t\"timestamp-field\": `timestamp`,\n\t\"timestamp-divisor\": 1000,\n\t\"module-field\": `package`,\n\t\"opid-field\": `service`,\n\t\"level-field\": `level`,\n\tlevel: {\n\t\tinfo: FLIGHTDECK_INFO,\n\t\twarning: FLIGHTDECK_WARN,\n\t\terror: FLIGHTDECK_ERROR,\n\t},\n\n\t[LINE_FORMAT]: [\n\t\t{\n\t\t\tfield: `level`,\n\t\t},\n\t\t{\n\t\t\tprefix: ` `,\n\t\t\tfield: `__timestamp__`,\n\t\t\t\"timestamp-format\": `%Y-%m-%dT%H:%M:%S.%L%Z`,\n\t\t},\n\t\t{\n\t\t\tprefix: ` `,\n\t\t\tfield: `process`,\n\t\t\t\"min-width\": 5,\n\t\t},\n\t\t{\n\t\t\tprefix: `:`,\n\t\t\tfield: `package`,\n\t\t},\n\t\t{\n\t\t\tprefix: `:`,\n\t\t\tfield: `service`,\n\t\t\t\"default-value\": ``,\n\t\t},\n\t\t{\n\t\t\tprefix: `: `,\n\t\t\tfield: `body`,\n\t\t},\n\t],\n\n\t[VALUE]: {\n\t\ttimestamp: {\n\t\t\tkind: `integer`,\n\t\t},\n\t\tlevel: {\n\t\t\tkind: `string`,\n\t\t},\n\t\tpackage: {\n\t\t\tkind: `string`,\n\t\t},\n\t\tservice: {\n\t\t\tkind: `string`,\n\t\t},\n\t\tprocess: {\n\t\t\tkind: `integer`,\n\t\t},\n\t\tbody: {\n\t\t\tkind: `string`,\n\t\t},\n\t},\n} as const satisfies FlightDeckFormat & LnavFormat\n\nexport class FlightDeckLogger implements Pick<\n\tConsole,\n\t`error` | `info` | `warn`\n> {\n\tpublic readonly packageName: string\n\tpublic readonly serviceName?: string\n\tpublic readonly jsonLogging: boolean\n\tpublic processCode: number\n\tpublic constructor(\n\t\tpackageName: string,\n\t\tprocessCode: number,\n\t\tserviceName?: string,\n\t\toptions?: { jsonLogging: boolean },\n\t) {\n\t\tthis.packageName = packageName\n\t\tif (serviceName) {\n\t\t\tthis.serviceName = serviceName\n\t\t}\n\t\tthis.processCode = processCode\n\t\tthis.jsonLogging = options?.jsonLogging ?? false\n\t}\n\tprotected log(\n\t\tlevel:\n\t\t\t| typeof FLIGHTDECK_ERROR\n\t\t\t| typeof FLIGHTDECK_INFO\n\t\t\t| typeof FLIGHTDECK_WARN,\n\t\t...messages: unknown[]\n\t): void {\n\t\tif (this.jsonLogging) {\n\t\t\tlet body = messages\n\t\t\t\t.map((message) =>\n\t\t\t\t\ttypeof message === `string`\n\t\t\t\t\t\t? message\n\t\t\t\t\t\t: inspect(message, false, null, true),\n\t\t\t\t)\n\t\t\t\t.join(` `)\n\t\t\tif (body.includes(`\\n`)) {\n\t\t\t\tbody = `\\n ${body.split(`\\n`).join(`\\n `)}`\n\t\t\t}\n\t\t\tconst log: FlightDeckLog = {\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t\tlevel,\n\t\t\t\tprocess: this.processCode,\n\t\t\t\tpackage: this.packageName,\n\t\t\t\tbody,\n\t\t\t}\n\t\t\tif (this.serviceName) {\n\t\t\t\tlog.service = this.serviceName\n\t\t\t}\n\t\t\tprocess.stdout.write(JSON.stringify(log) + `\\n`)\n\t\t} else {\n\t\t\tconst source = this.serviceName\n\t\t\t\t? `${this.packageName}:${this.serviceName}`\n\t\t\t\t: this.packageName\n\t\t\tswitch (level) {\n\t\t\t\tcase FLIGHTDECK_INFO:\n\t\t\t\t\tconsole.log(`${source}:`, ...messages)\n\t\t\t\t\tbreak\n\t\t\t\tcase FLIGHTDECK_WARN:\n\t\t\t\t\tconsole.warn(`${source}:`, ...messages)\n\t\t\t\t\tbreak\n\t\t\t\tcase FLIGHTDECK_ERROR:\n\t\t\t\t\tconsole.error(`${source}:`, ...messages)\n\t\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\tpublic info(...messages: unknown[]): void {\n\t\tthis.log(FLIGHTDECK_INFO, ...messages)\n\t}\n\n\tpublic warn(...messages: unknown[]): void {\n\t\tthis.log(FLIGHTDECK_WARN, ...messages)\n\t}\n\n\tpublic error(...messages: unknown[]): void {\n\t\tthis.log(FLIGHTDECK_ERROR, ...messages)\n\t}\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { c as FlightDeckLogger, s as FlightDeck } from "./flightdeck.lib-Dfs4xGO7.js";
2
+ import { c as FlightDeckLogger, s as FlightDeck } from "./flightdeck.lib-D19FU1Vu.js";
3
3
  import * as path from "node:path";
4
4
  import { type } from "arktype";
5
5
  import { cli, optional, options, parseBooleanOption, parseNumberOption } from "comline";
@@ -1,4 +1,4 @@
1
- import { t as __exportAll } from "./chunk-D7D4PA-g.js";
1
+ import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
2
  //#region src/klaxon.lib.ts
3
3
  var klaxon_lib_exports = /* @__PURE__ */ __exportAll({
4
4
  alert: () => alert,
@@ -34,4 +34,4 @@ async function scramble({ packageConfig, secretsConfig, publishedPackages }) {
34
34
  //#endregion
35
35
  export { scramble as n, klaxon_lib_exports as t };
36
36
 
37
- //# sourceMappingURL=klaxon.lib-Bgs1Mbca.js.map
37
+ //# sourceMappingURL=klaxon.lib-COgqK794.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"klaxon.lib-Bgs1Mbca.js","names":[],"sources":["../src/klaxon.lib.ts"],"sourcesContent":["export type AlertOptions = {\n\tsecret: string\n\tendpoint: string\n\tversion: string\n}\n\nexport async function alert({\n\tsecret,\n\tendpoint,\n\tversion,\n}: AlertOptions): Promise<Response> {\n\tconst response = await fetch(endpoint, {\n\t\tmethod: `POST`,\n\t\theaders: {\n\t\t\t\"Content-Type\": `text/plain;charset=UTF-8`,\n\t\t\tAuthorization: `Bearer ${secret}`,\n\t\t},\n\t\tbody: version,\n\t})\n\n\treturn response\n}\n\n/**\n * @see https://github.com/changesets/action/blob/main/src/run.ts\n */\nexport type ChangesetsPublishedPackage = {\n\tname: string\n\tversion: string\n}\n\n/**\n * @see https://github.com/changesets/action/blob/main/src/run.ts\n */\nexport type ChangesetsPublishResult =\n\t| {\n\t\t\tpublished: true\n\t\t\tpublishedPackages: ChangesetsPublishedPackage[]\n\t }\n\t| { published: false }\n\nexport type PackageConfig<K extends string> = {\n\t[key in K]: { endpoint: string }\n}\nexport type SecretsConfig<K extends string> = {\n\t[key in K]: string\n}\n\nexport type ScrambleOptions<K extends string = string> = {\n\tpackageConfig: PackageConfig<K>\n\tsecretsConfig: SecretsConfig<K>\n\tpublishedPackages: ChangesetsPublishedPackage[]\n}\n\nexport type ScrambleResult<K extends string = string> = {\n\t[key in K]: Response\n}\n\nexport async function scramble<K extends string = string>({\n\tpackageConfig,\n\tsecretsConfig,\n\tpublishedPackages,\n}: ScrambleOptions<K>): Promise<ScrambleResult<K>> {\n\tconst alertResults: Promise<readonly [K, Response]>[] = []\n\tfor (const publishedPackage of publishedPackages) {\n\t\tif (publishedPackage.name in packageConfig) {\n\t\t\tconst name = publishedPackage.name as K\n\t\t\tconst { endpoint } = packageConfig[name]\n\t\t\tconst secret = secretsConfig[name]\n\t\t\tconst version = publishedPackage.version\n\t\t\tconst alertResultPromise = alert({ secret, endpoint, version }).then(\n\t\t\t\t(alertResult) => [name, alertResult] as const,\n\t\t\t)\n\t\t\talertResults.push(alertResultPromise)\n\t\t}\n\t}\n\tconst alertResultsResolved = await Promise.all(alertResults)\n\tconst scrambleResult = Object.fromEntries(\n\t\talertResultsResolved,\n\t) as ScrambleResult<K>\n\treturn scrambleResult\n}\n"],"mappings":";;;;;;AAMA,eAAsB,MAAM,EAC3B,QACA,UACA,WACmC;CAUnC,OAAO,MATgB,MAAM,UAAU;EACtC,QAAQ;EACR,SAAS;GACR,gBAAgB;GAChB,eAAe,UAAU;EAC1B;EACA,MAAM;CACP,CAAC;AAGF;AAqCA,eAAsB,SAAoC,EACzD,eACA,eACA,qBACkD;CAClD,MAAM,eAAkD,CAAC;CACzD,KAAK,MAAM,oBAAoB,mBAC9B,IAAI,iBAAiB,QAAQ,eAAe;EAC3C,MAAM,OAAO,iBAAiB;EAC9B,MAAM,EAAE,aAAa,cAAc;EACnC,MAAM,SAAS,cAAc;EAC7B,MAAM,UAAU,iBAAiB;EACjC,MAAM,qBAAqB,MAAM;GAAE;GAAQ;GAAU;EAAQ,CAAC,CAAC,CAAC,MAC9D,gBAAgB,CAAC,MAAM,WAAW,CACpC;EACA,aAAa,KAAK,kBAAkB;CACrC;CAED,MAAM,uBAAuB,MAAM,QAAQ,IAAI,YAAY;CAI3D,OAHuB,OAAO,YAC7B,oBAEmB;AACrB"}
1
+ {"version":3,"file":"klaxon.lib-COgqK794.js","names":[],"sources":["../src/klaxon.lib.ts"],"sourcesContent":["export type AlertOptions = {\n\tsecret: string\n\tendpoint: string\n\tversion: string\n}\n\nexport async function alert({\n\tsecret,\n\tendpoint,\n\tversion,\n}: AlertOptions): Promise<Response> {\n\tconst response = await fetch(endpoint, {\n\t\tmethod: `POST`,\n\t\theaders: {\n\t\t\t\"Content-Type\": `text/plain;charset=UTF-8`,\n\t\t\tAuthorization: `Bearer ${secret}`,\n\t\t},\n\t\tbody: version,\n\t})\n\n\treturn response\n}\n\n/**\n * @see https://github.com/changesets/action/blob/main/src/run.ts\n */\nexport type ChangesetsPublishedPackage = {\n\tname: string\n\tversion: string\n}\n\n/**\n * @see https://github.com/changesets/action/blob/main/src/run.ts\n */\nexport type ChangesetsPublishResult =\n\t| {\n\t\t\tpublished: true\n\t\t\tpublishedPackages: ChangesetsPublishedPackage[]\n\t }\n\t| { published: false }\n\nexport type PackageConfig<K extends string> = {\n\t[key in K]: { endpoint: string }\n}\nexport type SecretsConfig<K extends string> = {\n\t[key in K]: string\n}\n\nexport type ScrambleOptions<K extends string = string> = {\n\tpackageConfig: PackageConfig<K>\n\tsecretsConfig: SecretsConfig<K>\n\tpublishedPackages: ChangesetsPublishedPackage[]\n}\n\nexport type ScrambleResult<K extends string = string> = {\n\t[key in K]: Response\n}\n\nexport async function scramble<K extends string = string>({\n\tpackageConfig,\n\tsecretsConfig,\n\tpublishedPackages,\n}: ScrambleOptions<K>): Promise<ScrambleResult<K>> {\n\tconst alertResults: Promise<readonly [K, Response]>[] = []\n\tfor (const publishedPackage of publishedPackages) {\n\t\tif (publishedPackage.name in packageConfig) {\n\t\t\tconst name = publishedPackage.name as K\n\t\t\tconst { endpoint } = packageConfig[name]\n\t\t\tconst secret = secretsConfig[name]\n\t\t\tconst version = publishedPackage.version\n\t\t\tconst alertResultPromise = alert({ secret, endpoint, version }).then(\n\t\t\t\t(alertResult) => [name, alertResult] as const,\n\t\t\t)\n\t\t\talertResults.push(alertResultPromise)\n\t\t}\n\t}\n\tconst alertResultsResolved = await Promise.all(alertResults)\n\tconst scrambleResult = Object.fromEntries(\n\t\talertResultsResolved,\n\t) as ScrambleResult<K>\n\treturn scrambleResult\n}\n"],"mappings":";;;;;;AAMA,eAAsB,MAAM,EAC3B,QACA,UACA,WACmC;CAUnC,OAAO,MATgB,MAAM,UAAU;EACtC,QAAQ;EACR,SAAS;GACR,gBAAgB;GAChB,eAAe,UAAU;EAC1B;EACA,MAAM;CACP,CAAC;AAGF;AAqCA,eAAsB,SAAoC,EACzD,eACA,eACA,qBACkD;CAClD,MAAM,eAAkD,CAAC;CACzD,KAAK,MAAM,oBAAoB,mBAC9B,IAAI,iBAAiB,QAAQ,eAAe;EAC3C,MAAM,OAAO,iBAAiB;EAC9B,MAAM,EAAE,aAAa,cAAc;EACnC,MAAM,SAAS,cAAc;EAC7B,MAAM,UAAU,iBAAiB;EACjC,MAAM,qBAAqB,MAAM;GAAE;GAAQ;GAAU;EAAQ,CAAC,CAAC,CAAC,MAC9D,gBAAgB,CAAC,MAAM,WAAW,CACpC;EACA,aAAa,KAAK,kBAAkB;CACrC;CAED,MAAM,uBAAuB,MAAM,QAAQ,IAAI,YAAY;CAI3D,OAHuB,OAAO,YAC7B,oBAEmB;AACrB"}
package/dist/klaxon.x.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { n as scramble } from "./klaxon.lib-Bgs1Mbca.js";
2
+ import { n as scramble } from "./klaxon.lib-COgqK794.js";
3
3
  import { type } from "arktype";
4
4
  import { cli, options, required } from "comline";
5
5
  //#region src/klaxon.x.ts
package/dist/lib.d.ts CHANGED
@@ -1,10 +1,9 @@
1
1
  import { ChildProcessWithoutNullStreams } from "node:child_process";
2
- import { Future } from "atom.io/internal";
2
+ import { Future } from "atom.io/foundations/future";
3
3
  import { ChildSocket } from "atom.io/realtime-server";
4
4
  import { CronJob } from "cron";
5
5
  import { FilesystemStorage } from "safedeposit";
6
6
  import { z } from "zod";
7
-
8
7
  //#region gen/lnav-format-schema.gen.d.ts
9
8
  declare const lnavFormatSchema: z.ZodObject<{
10
9
  regex: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
@@ -241,7 +240,7 @@ type FlightDeckOptions<S extends string = string> = {
241
240
  readonly services: { [service in S]: {
242
241
  run: string;
243
242
  waitFor: boolean;
244
- } };
243
+ }; };
245
244
  readonly scripts: {
246
245
  readonly download: string;
247
246
  readonly install: string;
@@ -262,13 +261,13 @@ declare class FlightDeck<S extends string = string> {
262
261
  }, {
263
262
  readyToUpdate: [];
264
263
  alive: [];
265
- }, ChildProcessWithoutNullStreams> | null };
266
- protected serviceIdx: { readonly [service in S]: number };
267
- defaultServicesReadyToUpdate: { readonly [service in S]: boolean };
268
- servicesReadyToUpdate: { [service in S]: boolean };
264
+ }, ChildProcessWithoutNullStreams> | null; };
265
+ protected serviceIdx: { readonly [service in S]: number; };
266
+ defaultServicesReadyToUpdate: { readonly [service in S]: boolean; };
267
+ servicesReadyToUpdate: { [service in S]: boolean; };
269
268
  autoRespawnDeadServices: boolean;
270
269
  protected logger: Pick<Console, `error` | `info` | `warn`>;
271
- protected serviceLoggers: { readonly [service in S]: FlightDeckLogger };
270
+ protected serviceLoggers: { readonly [service in S]: FlightDeckLogger; };
272
271
  protected updateAvailabilityChecker: CronJob | null;
273
272
  servicesLive: Future<void>[];
274
273
  servicesDead: Future<void>[];
@@ -309,7 +308,7 @@ type FlightDeckFormat = {
309
308
  }))[];
310
309
  [VALUE]: { [K in keyof FlightDeckLog]: LnavFormatValueDefinition & {
311
310
  kind: FlightDeckLog[K] extends number | undefined ? `integer` : FlightDeckLog[K] extends string | undefined ? `string` : never;
312
- } };
311
+ }; };
313
312
  };
314
313
  declare const FLIGHTDECK_LNAV_FORMAT: {
315
314
  readonly title: "FlightDeck Log";
@@ -388,11 +387,7 @@ type AlertOptions = {
388
387
  endpoint: string;
389
388
  version: string;
390
389
  };
391
- declare function alert({
392
- secret,
393
- endpoint,
394
- version
395
- }: AlertOptions): Promise<Response>;
390
+ declare function alert({ secret, endpoint, version }: AlertOptions): Promise<Response>;
396
391
  /**
397
392
  * @see https://github.com/changesets/action/blob/main/src/run.ts
398
393
  */
@@ -411,19 +406,15 @@ type ChangesetsPublishResult = {
411
406
  };
412
407
  type PackageConfig<K extends string> = { [key in K]: {
413
408
  endpoint: string;
414
- } };
415
- type SecretsConfig<K extends string> = { [key in K]: string };
409
+ }; };
410
+ type SecretsConfig<K extends string> = { [key in K]: string; };
416
411
  type ScrambleOptions<K extends string = string> = {
417
412
  packageConfig: PackageConfig<K>;
418
413
  secretsConfig: SecretsConfig<K>;
419
414
  publishedPackages: ChangesetsPublishedPackage[];
420
415
  };
421
- type ScrambleResult<K extends string = string> = { [key in K]: Response };
422
- declare function scramble<K extends string = string>({
423
- packageConfig,
424
- secretsConfig,
425
- publishedPackages
426
- }: ScrambleOptions<K>): Promise<ScrambleResult<K>>;
416
+ type ScrambleResult<K extends string = string> = { [key in K]: Response; };
417
+ declare function scramble<K extends string = string>({ packageConfig, secretsConfig, publishedPackages }: ScrambleOptions<K>): Promise<ScrambleResult<K>>;
427
418
  //#endregion
428
419
  export { FLIGHTDECK_ERROR, FLIGHTDECK_INFO, FLIGHTDECK_LNAV_FORMAT, FLIGHTDECK_SETUP_PHASES, FLIGHTDECK_UPDATE_PHASES, FLIGHTDECK_WARN, FlightDeck, FlightDeckFormat, FlightDeckLog, FlightDeckLogger, FlightDeckOptions, FlightDeckSaveData, FlightDeckSetupPhase, FlightDeckUpdatePhase, klaxon_lib_d_exports as Klaxon, LnavFormatBreakdown, LnavFormatValueDefinition, LnavFormatVisualComponent, MemberOf, isVersionNumber };
429
420
  //# sourceMappingURL=lib.d.ts.map
package/dist/lib.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"lib.d.ts","names":[],"sources":["../gen/lnav-format-schema.gen.ts","../src/flightdeck.lib.ts","../src/klaxon.lib.ts"],"mappings":";;;;;;;;cAEa,gBAAA,EAAgB,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAohDjB,UAAA,GAAa,CAAA,CAAE,KAAK,QAAQ,gBAAA;;;cCpgD3B,uBAAA;AAAA,KAED,oBAAA,WAA+B,uBAAuB;AAAA,cAErD,wBAAA;AAAA,KAED,qBAAA,WAAgC,wBAAwB;AAAA,iBAEpD,eAAA,CAAgB,OAAe;AAAA,KAMnC,kBAAA;EACX,UAAA;EACA,UAAA,EAAY,oBAAA;EACZ,WAAA,EAAa,qBAAqB;EAClC,oBAAA;AAAA;AAAA,KAGW,iBAAA;EAAA,SACF,WAAA;EAAA,SACA,QAAA,gBAAwB,CAAC;IAAK,GAAA;IAAa,OAAA;EAAA;EAAA,SAC3C,OAAA;IAAA,SACC,QAAA;IAAA,SACA,OAAA;IAAA,SACA,iBAAA;EAAA;EAAA,SAED,IAAA;EAAA,SACA,iBAAA;EAAA,SACA,WAAA;AAAA;AAAA,cA4CG,UAAA;EAAA,OACQ,IAAA,CACnB,iBAAA,UACA,WAAA,WACE,OAAA;EAAA,SAoBa,OAAA,EAAS,iBAAA,CAAkB,CAAA;EAAA,UACjC,MAAA;EAAA,UAEA,OAAA,EAAS,iBAAA,CAAkB,kBAAA;EAAA,UAC3B,QAAA,gBACG,CAAA,GAAI,WAAA;IACb,UAAA;IAAgB,YAAA;EAAA;IAChB,aAAA;IAAmB,KAAA;EAAA,GACrB,8BAAA;EAAA,UAGQ,UAAA,yBAAmC,CAAA;EACtC,4BAAA,yBAAqD,CAAA;EACrD,qBAAA,gBAAqC,CAAA;EACrC,uBAAA;EAAA,UAEG,MAAA,EAAQ,IAAA,CAAK,OAAA;EAAA,UACb,cAAA,yBACY,CAAA,GAAI,gBAAA;EAAA,UAGhB,yBAAA,EAA2B,OAAA;EAE9B,YAAA,EAAc,MAAA;EACd,YAAA,EAAc,MAAA;EACd,IAAA,EAAI,MAAA;EACJ,IAAA,EAAI,MAAA;EAAA,UAED,YAAA;cAES,OAAA,EAAS,iBAAA,CAAkB,CAAA;EAAA,UA0I9B,UAAA,CAAW,OAAA,WAAkB,OAAA;EAAA,UAwBnC,cAAA;EAAA,UAaA,SAAA;EAAA,UA2BA,gBAAA,IAAoB,MAAA;EAAA,UAwBpB,YAAA,CAAa,WAAA,EAAa,CAAA;EAAA,UA2E1B,eAAA;EAAA,UAeA,cAAA;EAgBH,eAAA,IAAmB,MAAA;EASnB,WAAA,CAAY,WAAA,EAAa,CAAA;AAAA;AAAA,cA8BpB,eAAA;AAAA,cACA,eAAA;AAAA,cACA,gBAAA;AAAA,KAED,aAAA;EACX,KAAA,SACU,gBAAA,UACA,eAAA,UACA,eAAA;EACV,SAAA;EACA,OAAA;EACA,OAAA;EACA,OAAA;EACA,IAAA;AAAA;AAAA,cAGK,WAAA;AAAA,cACA,KAAA;AAAA,KAEM,yBAAA,GAA4B,OAAA,CACvC,OAAA,CAAQ,UAAA;AAAA,KAIG,mBAAA,GAAsB,OAAO,CAAC,UAAA;AAAA,KAC9B,QAAA,MAAc,CAAA,OAAQ,CAAC;AAAA,KACvB,yBAAA,GAA4B,QAAQ,CAAC,mBAAA;AAAA,KAErC,gBAAA;EAAA,CACV,WAAA,cAEG,yBAAA;IACD,KAAA,QAAa,aAAA;EAAA;EAAA,CAGf,KAAA,iBACY,aAAA,GAAgB,yBAAA;IAC3B,IAAA,EAAM,aAAA,CAAc,CAAA,2CAEjB,aAAA,CAAc,CAAA;EAAA;AAAA;AAAA,cAOP,sBAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAkEA,gBAAA,YAA4B,IAAA,CACxC,OAAA;EAAA,SAGgB,WAAA;EAAA,SACA,WAAA;EAAA,SACA,WAAA;EACT,WAAA;cAEN,WAAA,UACA,WAAA,UACA,WAAA,WACA,OAAA;IAAY,WAAA;EAAA;EAAA,UASH,GAAA,CACT,KAAA,SACU,gBAAA,UACA,eAAA,UACA,eAAA,KACP,QAAA;EAyCG,IAAA,IAAQ,QAAA;EAIR,IAAA,IAAQ,QAAA;EAIR,KAAA,IAAS,QAAA;AAAA;AAAA;;;KCjsBL,YAAA;EACX,MAAA;EACA,QAAA;EACA,OAAA;AAAA;AAAA,iBAGqB,KAAA;EACrB,MAAA;EACA,QAAA;EACA;AAAA,GACE,YAAA,GAAe,OAAA,CAAQ,QAAA;;;;KAgBd,0BAAA;EACX,IAAA;EACA,OAAO;AAAA;;;;KAMI,uBAAA;EAET,SAAA;EACA,iBAAA,EAAmB,0BAA0B;AAAA;EAE3C,SAAA;AAAA;AAAA,KAEO,aAAA,+BACH,CAAC;EAAK,QAAA;AAAA;AAAA,KAEH,aAAA,+BACH,CAAC;AAAA,KAGE,eAAA;EACX,aAAA,EAAe,aAAA,CAAc,CAAA;EAC7B,aAAA,EAAe,aAAA,CAAc,CAAA;EAC7B,iBAAA,EAAmB,0BAAA;AAAA;AAAA,KAGR,cAAA,wCACH,CAAA,GAAI,QAAQ;AAAA,iBAGC,QAAA;EACrB,aAAA;EACA,aAAA;EACA;AAAA,GACE,eAAA,CAAgB,CAAA,IAAK,OAAA,CAAQ,cAAA,CAAe,CAAA"}
1
+ {"version":3,"file":"lib.d.ts","names":[],"sources":["../gen/lnav-format-schema.gen.ts","../src/flightdeck.lib.ts","../src/klaxon.lib.ts"],"mappings":";;;;;;;cAEa,kBAAgB,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAohDjB,aAAa,EAAE,aAAa;;;cCpgD3B;KAED,+BAA+B;cAE9B;KAED,gCAAgC;iBAE5B,gBAAgB;KAMpB;EACX;EACA,YAAY;EACZ,aAAa;EACb;;KAGW,kBAAkB;WACpB;WACA,aAAa,WAAW;IAAM;IAAa;;WAC3C;aACC;aACA;aACA;;WAED;WACA;WACA;;cA4CG,WAAW;SACH,KACnB,2BACA,sBACE;WAoBa,SAAS,kBAAkB;YACjC;YAEA,SAAS,kBAAkB;YAC3B,aACR,WAAW,IAAI;IACb;IAAgB;;IAChB;IAAmB;KACrB;YAGQ,wBAAwB,WAAW;EACtC,0CAA0C,WAAW;EACrD,0BAA0B,WAAW;EACrC;YAEG,QAAQ,KAAK;YACb,4BACC,WAAW,IAAI;YAGhB,2BAA2B;EAE9B,cAAc;EACd,cAAc;EACd,MAAI;EACJ,MAAI;YAED;cAES,SAAS,kBAAkB;YA0I9B,WAAW,kBAAkB;YAwBnC;YAaA;YA2BA,oBAAoB;YAwBpB,aAAa,aAAa;YA2E1B;YAeA;EAgBH,mBAAmB;EASnB,YAAY,aAAa;;cA8BpB;cACA;cACA;KAED;EACX,cACU,0BACA,yBACA;EACV;EACA;EACA;EACA;EACA;;cAGK;cACA;KAEM,4BAA4B,QACvC,QAAQ;KAIG,sBAAsB,QAAQ;KAC9B,SAAS,KAAK,QAAQ;KACtB,4BAA4B,SAAS;KAErC;GACV,yBAEG;IACD,aAAa;;GAGf,WACC,WAAW,gBAAgB;IAC3B,MAAM,cAAc,4CAEjB,cAAc;;;cAOP;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAkEA,4BAA4B,KACxC;WAGgB;WACA;WACA;EACT;cAEN,qBACA,qBACA,sBACA;IAAY;;YASH,IACT,cACU,0BACA,yBACA,oBACP;EAyCG,QAAQ;EAIR,QAAQ;EAIR,SAAS;;;;;KCjsBL;EACX;EACA;EACA;;iBAGqB,QACrB,QACA,UACA,WACE,eAAe,QAAQ;;;;KAgBd;EACX;EACA;;;;;KAMW;EAET;EACA,mBAAmB;;EAEjB;;KAEO,cAAc,uBACxB,OAAO;EAAM;;KAEH,cAAc,uBACxB,OAAO;KAGG,gBAAgB;EAC3B,eAAe,cAAc;EAC7B,eAAe,cAAc;EAC7B,mBAAmB;;KAGR,eAAe,gCACzB,OAAO,IAAI;iBAGS,SAAS,6BAC9B,eACA,eACA,qBACE,gBAAgB,KAAK,QAAQ,eAAe"}
package/dist/lib.js CHANGED
@@ -1,3 +1,3 @@
1
- import { a as FLIGHTDECK_UPDATE_PHASES, c as FlightDeckLogger, i as FLIGHTDECK_SETUP_PHASES, l as isVersionNumber, n as FLIGHTDECK_INFO, o as FLIGHTDECK_WARN, r as FLIGHTDECK_LNAV_FORMAT, s as FlightDeck, t as FLIGHTDECK_ERROR } from "./flightdeck.lib-Dfs4xGO7.js";
2
- import { t as klaxon_lib_exports } from "./klaxon.lib-Bgs1Mbca.js";
1
+ import { a as FLIGHTDECK_UPDATE_PHASES, c as FlightDeckLogger, i as FLIGHTDECK_SETUP_PHASES, l as isVersionNumber, n as FLIGHTDECK_INFO, o as FLIGHTDECK_WARN, r as FLIGHTDECK_LNAV_FORMAT, s as FlightDeck, t as FLIGHTDECK_ERROR } from "./flightdeck.lib-D19FU1Vu.js";
2
+ import { t as klaxon_lib_exports } from "./klaxon.lib-COgqK794.js";
3
3
  export { FLIGHTDECK_ERROR, FLIGHTDECK_INFO, FLIGHTDECK_LNAV_FORMAT, FLIGHTDECK_SETUP_PHASES, FLIGHTDECK_UPDATE_PHASES, FLIGHTDECK_WARN, FlightDeck, FlightDeckLogger, klaxon_lib_exports as Klaxon, isVersionNumber };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flightdeck",
3
- "version": "0.4.14",
3
+ "version": "0.4.15",
4
4
  "license": "MIT",
5
5
  "author": {
6
6
  "name": "Jeremy Banka",
@@ -31,25 +31,25 @@
31
31
  },
32
32
  "dependencies": {
33
33
  "@t3-oss/env-core": "0.13.11",
34
- "arktype": "2.2.0",
35
- "atom.io": "0.47.4",
34
+ "arktype": "2.2.3",
35
+ "atom.io": "0.49.7",
36
36
  "cron": "4.4.0",
37
- "comline": "0.5.0",
37
+ "comline": "0.5.1",
38
38
  "safedeposit": "0.1.2"
39
39
  },
40
40
  "devDependencies": {
41
41
  "@biomejs/js-api": "6.0.0",
42
- "@biomejs/wasm-nodejs": "2.5.0",
42
+ "@biomejs/wasm-nodejs": "2.5.3",
43
43
  "@types/bun": "npm:bun-types@1.3.14",
44
- "@types/node": "25.9.3",
45
- "@typescript/native-preview": "7.0.0-dev.20260615.1",
44
+ "@types/node": "25.9.5",
45
+ "@typescript/native-preview": "7.0.0-dev.20260707.2",
46
46
  "concurrently": "10.0.3",
47
- "eslint": "10.5.0",
47
+ "eslint": "10.6.0",
48
48
  "json-schema-to-zod": "2.8.1",
49
- "tsdown": "0.22.2",
50
- "vitest": "4.1.8",
49
+ "tsdown": "0.22.4",
50
+ "vitest": "4.1.10",
51
51
  "zod": "4.4.3",
52
- "varmint": "0.5.17"
52
+ "varmint": "0.5.18"
53
53
  },
54
54
  "scripts": {
55
55
  "gen": "bun ./__scripts__/gen.bun.ts",
@@ -6,9 +6,9 @@ import { homedir } from "node:os"
6
6
  import { resolve } from "node:path"
7
7
  import { inspect } from "node:util"
8
8
 
9
- import { Future } from "atom.io/internal"
9
+ import { fromEntries, toEntries } from "atom.io/foundations/entries"
10
+ import { Future } from "atom.io/foundations/future"
10
11
  import { discoverType } from "atom.io/introspection"
11
- import { fromEntries, toEntries } from "atom.io/json"
12
12
  import { ChildSocket } from "atom.io/realtime-server"
13
13
  import { CronJob } from "cron"
14
14
  import { FilesystemStorage } from "safedeposit"
@@ -1 +0,0 @@
1
- {"version":3,"file":"flightdeck.lib-Dfs4xGO7.js","names":[],"sources":["../src/flightdeck.env.ts","../src/flightdeck.lib.ts"],"sourcesContent":["import { createEnv } from \"@t3-oss/env-core\"\nimport { type } from \"arktype\"\n\nexport const env = createEnv({\n\tserver: { FLIGHTDECK_SECRET: type(`string`, `|`, `undefined`) },\n\tclientPrefix: `NEVER`,\n\tclient: {},\n\truntimeEnv: import.meta.env,\n\temptyStringAsUndefined: true,\n})\n","/* oxlint-disable typescript/only-throw-error */\nimport type { ChildProcessWithoutNullStreams } from \"node:child_process\"\nimport { execSync, spawn } from \"node:child_process\"\nimport { createServer } from \"node:http\"\nimport { homedir } from \"node:os\"\nimport { resolve } from \"node:path\"\nimport { inspect } from \"node:util\"\n\nimport { Future } from \"atom.io/internal\"\nimport { discoverType } from \"atom.io/introspection\"\nimport { fromEntries, toEntries } from \"atom.io/json\"\nimport { ChildSocket } from \"atom.io/realtime-server\"\nimport { CronJob } from \"cron\"\nimport { FilesystemStorage } from \"safedeposit\"\n\nimport type { LnavFormat } from \"../gen/lnav-format-schema.gen.ts\"\nimport { env } from \"./flightdeck.env.ts\"\n\nexport const FLIGHTDECK_SETUP_PHASES = [`downloaded`, `installed`] as const\n\nexport type FlightDeckSetupPhase = (typeof FLIGHTDECK_SETUP_PHASES)[number]\n\nexport const FLIGHTDECK_UPDATE_PHASES = [`notified`, `confirmed`] as const\n\nexport type FlightDeckUpdatePhase = (typeof FLIGHTDECK_UPDATE_PHASES)[number]\n\nexport function isVersionNumber(version: string): boolean {\n\treturn (\n\t\t/^\\d+\\.\\d+\\.\\d+$/.test(version) || !Number.isNaN(Number.parseFloat(version))\n\t)\n}\n\nexport type FlightDeckSaveData = {\n\tcurrentPid: `${number}`\n\tsetupPhase: FlightDeckSetupPhase\n\tupdatePhase: FlightDeckUpdatePhase\n\tupdateAwaitedVersion: string\n}\n\nexport type FlightDeckOptions<S extends string = string> = {\n\treadonly packageName: string\n\treadonly services: { [service in S]: { run: string; waitFor: boolean } }\n\treadonly scripts: {\n\t\treadonly download: string\n\t\treadonly install: string\n\t\treadonly checkAvailability?: string\n\t}\n\treadonly port?: number | undefined\n\treadonly flightdeckRootDir?: string | undefined\n\treadonly jsonLogging?: boolean | undefined\n}\n\nasync function waitForPidExit(pid: number, timeoutMs = 5000, intervalMs = 100) {\n\treturn new Promise<void>((pass, fail) => {\n\t\tconst start = Date.now()\n\n\t\tconst check = () => {\n\t\t\tprocess.stdout.write(`.`)\n\t\t\ttry {\n\t\t\t\t// check existence\n\t\t\t\tprocess.kill(pid, 0)\n\t\t\t\t// process still alive\n\t\t\t\tif (Date.now() - start > timeoutMs) {\n\t\t\t\t\tfail(new Error(`Timeout waiting for PID ${pid}`))\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tsetTimeout(check, intervalMs)\n\t\t\t} catch (err) {\n\t\t\t\tif (err instanceof Error && `code` in err) {\n\t\t\t\t\tif (err.code === `ESRCH`) {\n\t\t\t\t\t\tpass()\n\t\t\t\t\t\treturn // exited\n\t\t\t\t\t}\n\t\t\t\t\tif (err.code === `EPERM`) {\n\t\t\t\t\t\t// process is alive but protected\n\t\t\t\t\t\tif (Date.now() - start > timeoutMs) {\n\t\t\t\t\t\t\tfail(\n\t\t\t\t\t\t\t\tnew Error(`Timeout waiting for PID ${pid} (EPERM; still alive)`),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn setTimeout(check, intervalMs)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfail(err)\n\t\t\t\treturn // unexpected error\n\t\t\t}\n\t\t}\n\n\t\tcheck()\n\t})\n}\n\nexport class FlightDeck<S extends string = string> {\n\tpublic static async kill(\n\t\tflightdeckRootDir: string,\n\t\tpackageName: string,\n\t): Promise<number> {\n\t\tconsole.info(`Killing FlightDeck instance of \"${packageName}\"`)\n\t\tconst storage = new FilesystemStorage<FlightDeckSaveData>({\n\t\t\tpath: resolve(flightdeckRootDir, `storage`, packageName),\n\t\t})\n\t\tconst currentPid = storage.getItem(`currentPid`)\n\t\tif (currentPid === null) {\n\t\t\tthrow new Error(`No pid for \"${packageName}\" found in storage`)\n\t\t}\n\t\tconst pid = Number(currentPid)\n\t\tconst now = Date.now()\n\t\tprocess.kill(pid, `SIGTERM`)\n\t\tawait waitForPidExit(pid, 5000, 5)\n\t\tconst elapsed = Date.now() - now\n\t\tprocess.stdout.write(\n\t\t\t`🌜 \"${packageName}\" (running as process ${pid}) exited in ${elapsed}ms\\n`,\n\t\t)\n\t\treturn pid\n\t}\n\n\tpublic readonly options: FlightDeckOptions<S>\n\tprotected safety = 0\n\n\tprotected storage: FilesystemStorage<FlightDeckSaveData>\n\tprotected services: {\n\t\t[service in S]: ChildSocket<\n\t\t\t{ timeToStop: []; updatesReady: [] },\n\t\t\t{ readyToUpdate: []; alive: [] },\n\t\t\tChildProcessWithoutNullStreams\n\t\t> | null\n\t}\n\tprotected serviceIdx: { readonly [service in S]: number }\n\tpublic defaultServicesReadyToUpdate: { readonly [service in S]: boolean }\n\tpublic servicesReadyToUpdate: { [service in S]: boolean }\n\tpublic autoRespawnDeadServices: boolean\n\n\tprotected logger: Pick<Console, `error` | `info` | `warn`>\n\tprotected serviceLoggers: {\n\t\treadonly [service in S]: FlightDeckLogger\n\t}\n\n\tprotected updateAvailabilityChecker: CronJob | null = null\n\n\tpublic servicesLive: Future<void>[]\n\tpublic servicesDead: Future<void>[]\n\tpublic live = new Future(() => {})\n\tpublic dead = new Future(() => {})\n\n\tprotected restartTimes: number[] = []\n\n\tpublic constructor(options: FlightDeckOptions<S>) {\n\t\tthis.options = options\n\t\tconst { FLIGHTDECK_SECRET } = env\n\t\tconst { flightdeckRootDir = resolve(homedir(), `.flightdeck`) } = options\n\t\tconst port = options.port ?? 8080\n\t\tconst origin = `http://localhost:${port}`\n\n\t\tconst servicesEntries = toEntries(options.services)\n\t\tthis.services = fromEntries(\n\t\t\tservicesEntries.map(([serviceName]) => [serviceName, null]),\n\t\t)\n\t\tthis.serviceIdx = fromEntries(\n\t\t\tservicesEntries.map(([serviceName], idx) => [serviceName, idx]),\n\t\t)\n\t\tthis.defaultServicesReadyToUpdate = fromEntries(\n\t\t\tservicesEntries.map(([serviceName, { waitFor }]) => [\n\t\t\t\tserviceName,\n\t\t\t\t!waitFor,\n\t\t\t]),\n\t\t)\n\t\tthis.servicesReadyToUpdate = { ...this.defaultServicesReadyToUpdate }\n\t\tthis.autoRespawnDeadServices = true\n\n\t\tthis.logger = new FlightDeckLogger(\n\t\t\tthis.options.packageName,\n\t\t\tprocess.pid,\n\t\t\tundefined,\n\t\t\t{ jsonLogging: this.options.jsonLogging ?? false },\n\t\t)\n\t\tthis.serviceLoggers = fromEntries(\n\t\t\tservicesEntries.map(([serviceName]) => [\n\t\t\t\tserviceName,\n\t\t\t\tnew FlightDeckLogger(\n\t\t\t\t\tthis.options.packageName,\n\t\t\t\t\tprocess.pid,\n\t\t\t\t\tserviceName,\n\t\t\t\t\t{ jsonLogging: this.options.jsonLogging ?? false },\n\t\t\t\t),\n\t\t\t]),\n\t\t)\n\n\t\tthis.servicesLive = servicesEntries.map(() => new Future(() => {}))\n\t\tthis.servicesDead = servicesEntries.map(() => new Future(() => {}))\n\t\tthis.live.use(Promise.all(this.servicesLive))\n\t\tthis.dead.use(Promise.all(this.servicesDead))\n\n\t\tthis.storage = new FilesystemStorage({\n\t\t\tpath: resolve(flightdeckRootDir, `storage`, options.packageName),\n\t\t})\n\n\t\tthis.storage.setItem(`currentPid`, `${process.pid}`)\n\n\t\tif (FLIGHTDECK_SECRET === undefined) {\n\t\t\tthis.logger.warn(\n\t\t\t\t`No FLIGHTDECK_SECRET environment variable found. FlightDeck will not run an update server.`,\n\t\t\t)\n\t\t} else {\n\t\t\tcreateServer((req, res) => {\n\t\t\t\tlet data: Uint8Array[] = []\n\t\t\t\treq\n\t\t\t\t\t.on(`data`, (chunk) => {\n\t\t\t\t\t\tdata.push(chunk instanceof Buffer ? chunk : Buffer.from(chunk))\n\t\t\t\t\t})\n\t\t\t\t\t.on(`end`, async () => {\n\t\t\t\t\t\tconst authHeader = req.headers.authorization\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tif (typeof req.url === `undefined`) throw 400\n\t\t\t\t\t\t\tconst expectedAuthHeader = `Bearer ${FLIGHTDECK_SECRET}`\n\t\t\t\t\t\t\tif (authHeader !== `Bearer ${FLIGHTDECK_SECRET}`) {\n\t\t\t\t\t\t\t\tthis.logger.info(\n\t\t\t\t\t\t\t\t\t`Unauthorized: needed \\`${expectedAuthHeader}\\`, got \\`${authHeader}\\``,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\tthrow 401\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst url = new URL(req.url, origin)\n\t\t\t\t\t\t\tthis.logger.info(req.method, url.pathname)\n\n\t\t\t\t\t\t\tconst versionForeignInput = Buffer.concat(data).toString()\n\t\t\t\t\t\t\tif (!isVersionNumber(versionForeignInput)) {\n\t\t\t\t\t\t\t\tthrow 400\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tres.writeHead(200)\n\t\t\t\t\t\t\tres.end()\n\n\t\t\t\t\t\t\tthis.storage.setItem(`updatePhase`, `notified`)\n\t\t\t\t\t\t\tthis.storage.setItem(`updateAwaitedVersion`, versionForeignInput)\n\t\t\t\t\t\t\tconst { checkAvailability } = options.scripts\n\t\t\t\t\t\t\tif (checkAvailability) {\n\t\t\t\t\t\t\t\tawait this.updateAvailabilityChecker?.stop()\n\t\t\t\t\t\t\t\tawait this.seekUpdate(versionForeignInput)\n\t\t\t\t\t\t\t\tconst updatePhase = this.storage.getItem(`updatePhase`)\n\t\t\t\t\t\t\t\tthis.logger.info(`> storage(\"updatePhase\") >`, updatePhase)\n\t\t\t\t\t\t\t\tif (updatePhase === `notified`) {\n\t\t\t\t\t\t\t\t\tthis.updateAvailabilityChecker = new CronJob(\n\t\t\t\t\t\t\t\t\t\t`*/30 * * * * *`,\n\t\t\t\t\t\t\t\t\t\tasync () => {\n\t\t\t\t\t\t\t\t\t\t\tawait this.seekUpdate(versionForeignInput)\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\tthis.updateAvailabilityChecker.start()\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.downloadPackage()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch (thrown) {\n\t\t\t\t\t\t\tthis.logger.error(thrown, req.url)\n\t\t\t\t\t\t\tif (typeof thrown === `number`) {\n\t\t\t\t\t\t\t\tres.writeHead(thrown)\n\t\t\t\t\t\t\t\tres.end()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} finally {\n\t\t\t\t\t\t\tdata = []\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t}).listen(port, () => {\n\t\t\t\tthis.logger.info(`Server started on port ${port}`)\n\t\t\t})\n\t\t}\n\n\t\tthis.startAllServices()\n\t\t\t.then(() => {\n\t\t\t\tthis.logger.info(`All services started.`)\n\t\t\t})\n\t\t\t.catch((thrown) => {\n\t\t\t\tif (thrown instanceof Error) {\n\t\t\t\t\tthis.logger.error(`Failed to start all services:`, thrown.message)\n\t\t\t\t}\n\t\t\t})\n\n\t\tprocess.on(`SIGTERM`, async () => {\n\t\t\tconsole.info(`Killed by SIGTERM`)\n\t\t\tawait this.stopAllServices()\n\t\t\tthis.storage.removeItem(`currentPid`)\n\t\t\tprocess.exit(0)\n\t\t})\n\t}\n\n\tprotected async seekUpdate(version: string): Promise<void> {\n\t\tthis.logger.info(`Checking for updates...`)\n\t\tconst { checkAvailability } = this.options.scripts\n\t\tif (!checkAvailability) {\n\t\t\tthis.logger.info(`No checkAvailability script found.`)\n\t\t\treturn\n\t\t}\n\t\ttry {\n\t\t\tconst out = execSync(`${checkAvailability} ${version}`)\n\t\t\tthis.logger.info(`Check stdout:`, out.toString())\n\t\t\tawait this.updateAvailabilityChecker?.stop()\n\t\t\tthis.storage.setItem(`updatePhase`, `confirmed`)\n\t\t\tthis.downloadPackage()\n\t\t\tthis.announceUpdate()\n\t\t} catch (thrown) {\n\t\t\tif (thrown instanceof Error) {\n\t\t\t\tthis.logger.error(`Check failed:`, thrown.message)\n\t\t\t} else {\n\t\t\t\tconst thrownType = discoverType(thrown)\n\t\t\t\tthis.logger.error(`Check threw`, thrownType, thrown)\n\t\t\t}\n\t\t}\n\t}\n\n\tprotected announceUpdate(): void {\n\t\tfor (const entry of toEntries(this.services)) {\n\t\t\tconst [serviceName, service] = entry\n\t\t\tif (service) {\n\t\t\t\tif (this.options.services[serviceName].waitFor) {\n\t\t\t\t\tservice.emit(`updatesReady`)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis.startService(serviceName)\n\t\t\t}\n\t\t}\n\t}\n\n\tprotected tryUpdate(): void {\n\t\tif (toEntries(this.servicesReadyToUpdate).every(([, isReady]) => isReady)) {\n\t\t\tthis.logger.info(`All services are ready to update.`)\n\t\t\tthis.stopAllServices()\n\t\t\t\t.then(() => {\n\t\t\t\t\tthis.logger.info(`All services stopped; starting up fresh...`)\n\t\t\t\t\tthis.startAllServices()\n\t\t\t\t\t\t.then(() => {\n\t\t\t\t\t\t\tthis.logger.info(`All services started; we're back online.`)\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.catch((thrown) => {\n\t\t\t\t\t\t\tif (thrown instanceof Error) {\n\t\t\t\t\t\t\t\tthis.logger.error(\n\t\t\t\t\t\t\t\t\t`Failed to start all services:`,\n\t\t\t\t\t\t\t\t\tthrown.message,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t\t.catch((thrown) => {\n\t\t\t\t\tif (thrown instanceof Error) {\n\t\t\t\t\t\tthis.logger.error(`Failed to stop all services:`, thrown.message)\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t}\n\t}\n\n\tprotected startAllServices(): Future<unknown> {\n\t\tthis.logger.info(`Starting all services...`)\n\t\tthis.autoRespawnDeadServices = true\n\t\tconst setupPhase = this.storage.getItem(`setupPhase`)\n\t\tthis.logger.info(`> storage(\"setupPhase\") >`, setupPhase)\n\t\tswitch (setupPhase) {\n\t\t\tcase null:\n\t\t\t\tthis.logger.info(`Starting from scratch.`)\n\t\t\t\tthis.downloadPackage()\n\t\t\t\tthis.installPackage()\n\t\t\t\treturn this.startAllServices()\n\t\t\tcase `downloaded`:\n\t\t\t\tthis.logger.info(`Found package downloaded but not installed.`)\n\t\t\t\tthis.installPackage()\n\t\t\t\treturn this.startAllServices()\n\t\t\tcase `installed`: {\n\t\t\t\tfor (const [serviceName] of toEntries(this.services)) {\n\t\t\t\t\tthis.startService(serviceName)\n\t\t\t\t}\n\t\t\t\treturn this.live\n\t\t\t}\n\t\t}\n\t}\n\n\tprotected startService(serviceName: S): void {\n\t\tthis.logger.info(\n\t\t\t`Starting service ${this.options.packageName}::${serviceName}, try ${this.safety}/2...`,\n\t\t)\n\t\tif (this.safety >= 2) {\n\t\t\tthrow new Error(`Out of tries...`)\n\t\t}\n\t\tthis.safety++\n\n\t\tconst [exe, ...args] = this.options.services[serviceName].run.split(` `)\n\t\tconst serviceProcess = spawn(exe, args, {\n\t\t\tcwd: this.options.flightdeckRootDir,\n\t\t\tenv: import.meta.env,\n\t\t})\n\t\tconst serviceLogger = this.serviceLoggers[serviceName]\n\t\tconst service = (this.services[serviceName] = new ChildSocket(\n\t\t\tserviceProcess,\n\t\t\t`${this.options.packageName}::${serviceName}`,\n\t\t\tserviceLogger,\n\t\t))\n\t\tserviceLogger.processCode = service.proc.pid ?? -1\n\t\tthis.services[serviceName].onAny((...messages) => {\n\t\t\tserviceLogger.info(`💬`, ...messages)\n\t\t})\n\t\tthis.services[serviceName].on(`readyToUpdate`, () => {\n\t\t\tthis.logger.info(`Service \"${serviceName}\" is ready to update.`)\n\t\t\tthis.servicesReadyToUpdate[serviceName] = true\n\t\t\tthis.tryUpdate()\n\t\t})\n\t\tthis.services[serviceName].on(`alive`, () => {\n\t\t\tthis.servicesLive[this.serviceIdx[serviceName]].use(Promise.resolve())\n\t\t\tthis.servicesDead[this.serviceIdx[serviceName]] = new Future(() => {})\n\t\t\tif (this.dead.done) {\n\t\t\t\tthis.dead = new Future(() => {})\n\t\t\t}\n\t\t\tthis.dead.use(Promise.all(this.servicesDead))\n\t\t})\n\t\tthis.services[serviceName].proc.once(`close`, (exitCode) => {\n\t\t\tthis.logger.info(\n\t\t\t\t`Auto-respawn saw \"${serviceName}\" exit with code ${exitCode}`,\n\t\t\t)\n\t\t\tthis.services[serviceName] = null\n\t\t\tif (!this.autoRespawnDeadServices) {\n\t\t\t\tthis.logger.info(`😴 Auto-respawn is off; \"${serviceName}\" rests.`)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst updatePhase = this.storage.getItem(`updatePhase`)\n\t\t\tthis.logger.info(`> storage(\"updatePhase\") >`, updatePhase)\n\t\t\tconst updatesAreReady = updatePhase === `confirmed`\n\t\t\tif (updatesAreReady) {\n\t\t\t\tthis.serviceLoggers[serviceName].info(`Updating before startup...`)\n\t\t\t\tthis.restartTimes = []\n\t\t\t\tthis.installPackage()\n\t\t\t\tthis.startService(serviceName)\n\t\t\t} else {\n\t\t\t\tconst now = Date.now()\n\t\t\t\tconst fiveMinutesAgo = now - 5 * 60 * 1000\n\t\t\t\tthis.restartTimes = this.restartTimes.filter(\n\t\t\t\t\t(time) => time > fiveMinutesAgo,\n\t\t\t\t)\n\t\t\t\tthis.restartTimes.push(now)\n\n\t\t\t\tif (this.restartTimes.length < 5) {\n\t\t\t\t\tthis.serviceLoggers[serviceName].info(`Crashed. Restarting...`)\n\t\t\t\t\tthis.startService(serviceName)\n\t\t\t\t} else {\n\t\t\t\t\tthis.serviceLoggers[serviceName].info(\n\t\t\t\t\t\t`Crashed 5 times in 5 minutes. Not restarting.`,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t\tthis.safety = 0\n\t}\n\n\tprotected downloadPackage(): void {\n\t\tthis.logger.info(`Downloading...`)\n\t\ttry {\n\t\t\tconst out = execSync(this.options.scripts.download)\n\t\t\tthis.logger.info(`Download stdout:`, out.toString())\n\t\t\tthis.storage.setItem(`setupPhase`, `downloaded`)\n\t\t\tthis.logger.info(`Downloaded!`)\n\t\t} catch (thrown) {\n\t\t\tif (thrown instanceof Error) {\n\t\t\t\tthis.logger.error(`Failed to get the latest release: ${thrown.message}`)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t}\n\n\tprotected installPackage(): void {\n\t\tthis.logger.info(`Installing...`)\n\n\t\ttry {\n\t\t\tconst out = execSync(this.options.scripts.install)\n\t\t\tthis.logger.info(`Install stdout:`, out.toString())\n\t\t\tthis.storage.setItem(`setupPhase`, `installed`)\n\t\t\tthis.logger.info(`Installed!`)\n\t\t} catch (thrown) {\n\t\t\tif (thrown instanceof Error) {\n\t\t\t\tthis.logger.error(`Failed to get the latest release: ${thrown.message}`)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t}\n\n\tpublic stopAllServices(): Future<unknown> {\n\t\tthis.logger.info(`Stopping all services... auto-respawn disabled.`)\n\t\tthis.autoRespawnDeadServices = false\n\t\tfor (const [serviceName] of toEntries(this.services)) {\n\t\t\tthis.stopService(serviceName)\n\t\t}\n\t\treturn this.dead\n\t}\n\n\tpublic stopService(serviceName: S): void {\n\t\tconst service = this.services[serviceName]\n\t\tif (service) {\n\t\t\tthis.logger.info(`Stopping service \"${serviceName}\"...`)\n\t\t\tthis.servicesDead[this.serviceIdx[serviceName]].use(\n\t\t\t\tnew Promise((pass) => {\n\t\t\t\t\tservice.emit(`timeToStop`)\n\t\t\t\t\tservice.proc.once(`close`, (exitCode) => {\n\t\t\t\t\t\tthis.logger.info(\n\t\t\t\t\t\t\t`Stopped service \"${serviceName}\"; exited with code ${exitCode}`,\n\t\t\t\t\t\t)\n\t\t\t\t\t\tthis.services[serviceName] = null\n\t\t\t\t\t\tpass()\n\t\t\t\t\t})\n\t\t\t\t}),\n\t\t\t)\n\t\t\tthis.dead.use(Promise.all(this.servicesDead))\n\t\t\tthis.servicesLive[this.serviceIdx[serviceName]] = new Future(() => {})\n\t\t\tif (this.live.done) {\n\t\t\t\tthis.live = new Future(() => {})\n\t\t\t}\n\t\t\tthis.live.use(Promise.all(this.servicesLive))\n\t\t} else {\n\t\t\tthis.serviceLoggers[serviceName].error(\n\t\t\t\t`Tried to stop service, but it wasn't running.`,\n\t\t\t)\n\t\t}\n\t}\n}\n\nexport const FLIGHTDECK_INFO = `info`\nexport const FLIGHTDECK_WARN = `warn`\nexport const FLIGHTDECK_ERROR = `ERR!`\n\nexport type FlightDeckLog = {\n\tlevel:\n\t\t| typeof FLIGHTDECK_ERROR\n\t\t| typeof FLIGHTDECK_INFO\n\t\t| typeof FLIGHTDECK_WARN\n\ttimestamp: number\n\tpackage: string\n\tservice?: string\n\tprocess: number\n\tbody: string\n}\n\nconst LINE_FORMAT = `line-format` satisfies keyof LnavFormat\nconst VALUE = `value` satisfies keyof LnavFormat\n\nexport type LnavFormatVisualComponent = Exclude<\n\tExclude<LnavFormat[`line-format`], undefined>[number],\n\tstring\n>\n\nexport type LnavFormatBreakdown = Exclude<LnavFormat[`value`], undefined>\nexport type MemberOf<T> = T[keyof T]\nexport type LnavFormatValueDefinition = MemberOf<LnavFormatBreakdown>\n\nexport type FlightDeckFormat = {\n\t[LINE_FORMAT]: (\n\t\t| string\n\t\t| (LnavFormatVisualComponent & {\n\t\t\t\tfield: keyof FlightDeckLog | `__level__` | `__timestamp__`\n\t\t })\n\t)[]\n\t[VALUE]: {\n\t\t[K in keyof FlightDeckLog]: LnavFormatValueDefinition & {\n\t\t\tkind: FlightDeckLog[K] extends number | undefined\n\t\t\t\t? `integer`\n\t\t\t\t: FlightDeckLog[K] extends string | undefined\n\t\t\t\t\t? `string`\n\t\t\t\t\t: never\n\t\t}\n\t}\n}\n\nexport const FLIGHTDECK_LNAV_FORMAT = {\n\ttitle: `FlightDeck Log`,\n\tdescription: `Format for events logged by the FlightDeck process manager.`,\n\t\"file-type\": `json`,\n\t\"timestamp-field\": `timestamp`,\n\t\"timestamp-divisor\": 1000,\n\t\"module-field\": `package`,\n\t\"opid-field\": `service`,\n\t\"level-field\": `level`,\n\tlevel: {\n\t\tinfo: FLIGHTDECK_INFO,\n\t\twarning: FLIGHTDECK_WARN,\n\t\terror: FLIGHTDECK_ERROR,\n\t},\n\n\t[LINE_FORMAT]: [\n\t\t{\n\t\t\tfield: `level`,\n\t\t},\n\t\t{\n\t\t\tprefix: ` `,\n\t\t\tfield: `__timestamp__`,\n\t\t\t\"timestamp-format\": `%Y-%m-%dT%H:%M:%S.%L%Z`,\n\t\t},\n\t\t{\n\t\t\tprefix: ` `,\n\t\t\tfield: `process`,\n\t\t\t\"min-width\": 5,\n\t\t},\n\t\t{\n\t\t\tprefix: `:`,\n\t\t\tfield: `package`,\n\t\t},\n\t\t{\n\t\t\tprefix: `:`,\n\t\t\tfield: `service`,\n\t\t\t\"default-value\": ``,\n\t\t},\n\t\t{\n\t\t\tprefix: `: `,\n\t\t\tfield: `body`,\n\t\t},\n\t],\n\n\t[VALUE]: {\n\t\ttimestamp: {\n\t\t\tkind: `integer`,\n\t\t},\n\t\tlevel: {\n\t\t\tkind: `string`,\n\t\t},\n\t\tpackage: {\n\t\t\tkind: `string`,\n\t\t},\n\t\tservice: {\n\t\t\tkind: `string`,\n\t\t},\n\t\tprocess: {\n\t\t\tkind: `integer`,\n\t\t},\n\t\tbody: {\n\t\t\tkind: `string`,\n\t\t},\n\t},\n} as const satisfies FlightDeckFormat & LnavFormat\n\nexport class FlightDeckLogger implements Pick<\n\tConsole,\n\t`error` | `info` | `warn`\n> {\n\tpublic readonly packageName: string\n\tpublic readonly serviceName?: string\n\tpublic readonly jsonLogging: boolean\n\tpublic processCode: number\n\tpublic constructor(\n\t\tpackageName: string,\n\t\tprocessCode: number,\n\t\tserviceName?: string,\n\t\toptions?: { jsonLogging: boolean },\n\t) {\n\t\tthis.packageName = packageName\n\t\tif (serviceName) {\n\t\t\tthis.serviceName = serviceName\n\t\t}\n\t\tthis.processCode = processCode\n\t\tthis.jsonLogging = options?.jsonLogging ?? false\n\t}\n\tprotected log(\n\t\tlevel:\n\t\t\t| typeof FLIGHTDECK_ERROR\n\t\t\t| typeof FLIGHTDECK_INFO\n\t\t\t| typeof FLIGHTDECK_WARN,\n\t\t...messages: unknown[]\n\t): void {\n\t\tif (this.jsonLogging) {\n\t\t\tlet body = messages\n\t\t\t\t.map((message) =>\n\t\t\t\t\ttypeof message === `string`\n\t\t\t\t\t\t? message\n\t\t\t\t\t\t: inspect(message, false, null, true),\n\t\t\t\t)\n\t\t\t\t.join(` `)\n\t\t\tif (body.includes(`\\n`)) {\n\t\t\t\tbody = `\\n ${body.split(`\\n`).join(`\\n `)}`\n\t\t\t}\n\t\t\tconst log: FlightDeckLog = {\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t\tlevel,\n\t\t\t\tprocess: this.processCode,\n\t\t\t\tpackage: this.packageName,\n\t\t\t\tbody,\n\t\t\t}\n\t\t\tif (this.serviceName) {\n\t\t\t\tlog.service = this.serviceName\n\t\t\t}\n\t\t\tprocess.stdout.write(JSON.stringify(log) + `\\n`)\n\t\t} else {\n\t\t\tconst source = this.serviceName\n\t\t\t\t? `${this.packageName}:${this.serviceName}`\n\t\t\t\t: this.packageName\n\t\t\tswitch (level) {\n\t\t\t\tcase FLIGHTDECK_INFO:\n\t\t\t\t\tconsole.log(`${source}:`, ...messages)\n\t\t\t\t\tbreak\n\t\t\t\tcase FLIGHTDECK_WARN:\n\t\t\t\t\tconsole.warn(`${source}:`, ...messages)\n\t\t\t\t\tbreak\n\t\t\t\tcase FLIGHTDECK_ERROR:\n\t\t\t\t\tconsole.error(`${source}:`, ...messages)\n\t\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\tpublic info(...messages: unknown[]): void {\n\t\tthis.log(FLIGHTDECK_INFO, ...messages)\n\t}\n\n\tpublic warn(...messages: unknown[]): void {\n\t\tthis.log(FLIGHTDECK_WARN, ...messages)\n\t}\n\n\tpublic error(...messages: unknown[]): void {\n\t\tthis.log(FLIGHTDECK_ERROR, ...messages)\n\t}\n}\n"],"mappings":"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"}