UNPKG

everything-dev

Version:

A consolidated product package for building Module Federation apps with oRPC APIs.

83 lines (81 loc) 2.8 kB
import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs"; import { join } from "node:path"; import { Effect } from "effect"; import { access } from "node:fs/promises"; import { homedir } from "node:os"; //#region src/process-registry.ts function getRegistryDir() { return join(homedir(), ".cache", "everything-dev"); } function ensureRegistryDir() { const dir = join(getRegistryPath(), ".."); if (!existsSync(dir)) mkdirSync(dir, { recursive: true }); } function readRegistry() { const path = getRegistryPath(); if (!existsSync(path)) return []; try { const raw = JSON.parse(readFileSync(path, "utf-8")); if (!Array.isArray(raw)) return []; return raw.filter((entry) => entry && typeof entry === "object" && typeof entry.pid === "number" && typeof entry.configDir === "string" && typeof entry.role === "string"); } catch { return []; } } function isPidAlive(pid) { try { process.kill(pid, 0); return true; } catch (err) { return err.code !== "ESRCH"; } } function pruneDead(entries) { return entries.filter((entry) => entry.pid > 1 && existsSync(entry.configDir) && isPidAlive(entry.pid)); } function pruneDeadEffect(entries) { return Effect.forEach(entries, (entry) => { if (entry.pid <= 1) return Effect.succeed(null); return Effect.gen(function* () { if (!(yield* Effect.promise(() => access(entry.configDir).then(() => true).catch(() => false)))) return null; if (!isPidAlive(entry.pid)) return null; return entry; }); }, { concurrency: "unbounded" }).pipe(Effect.map((results) => results.filter((e) => e !== null))); } function writeRegistry(entries) { ensureRegistryDir(); const path = getRegistryPath(); const tmpPath = `${path}.tmp`; writeFileSync(tmpPath, `${JSON.stringify(entries, null, 2)}\n`); renameSync(tmpPath, path); } function registerStandalone(entry) { const live = pruneDead(readRegistry()); const full = { ...entry, role: "standalone" }; const withoutSelf = live.filter((existing) => existing.pid !== entry.pid); withoutSelf.push(full); writeRegistry(withoutSelf); return full; } function unregisterPid(pid) { const live = pruneDead(readRegistry()); const next = live.filter((entry) => entry.pid !== pid); if (next.length === live.length) return; writeRegistry(next); } function getRegistryPath() { return process.env.BO_PID_REGISTRY_PATH ?? join(getRegistryDir(), "pids.json"); } function claimedPorts() { const live = pruneDead(readRegistry()); const out = /* @__PURE__ */ new Set(); for (const entry of live) for (const port of Object.values(entry.ports)) if (typeof port === "number") out.add(port); return out; } //#endregion export { claimedPorts, pruneDeadEffect, readRegistry, registerStandalone, unregisterPid }; //# sourceMappingURL=process-registry.mjs.map