first-commit
ci / Validate workspace (push) Has been cancelled
landing-page-ci / Validate landing page (push) Has been cancelled
landing-page-deploy / Deploy landing page (push) Has been cancelled
github-metrics / Generate repository metrics SVG (push) Has been cancelled
refresh-contributors-wall / Refresh contributors wall cache bust (push) Waiting to run

This commit is contained in:
Zakaria
2026-05-04 14:58:14 -04:00
commit a46764fb1b
1210 changed files with 233231 additions and 0 deletions
+11
View File
@@ -0,0 +1,11 @@
import { build } from "esbuild";
await build({
bundle: true,
entryPoints: ["./src/index.ts"],
format: "esm",
outfile: "./dist/index.mjs",
packages: "external",
platform: "node",
target: "node24",
});
+31
View File
@@ -0,0 +1,31 @@
{
"name": "@open-design/sidecar",
"version": "0.3.0",
"private": true,
"type": "module",
"main": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"files": [
"dist"
],
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.mjs"
}
},
"scripts": {
"build": "node ./esbuild.config.mjs && tsc -p tsconfig.json --emitDeclarationOnly",
"test": "vitest run",
"typecheck": "tsc -p tsconfig.json --noEmit"
},
"devDependencies": {
"@types/node": "24.12.2",
"esbuild": "0.27.7",
"vitest": "^2.1.8",
"typescript": "6.0.3"
},
"engines": {
"node": "~24"
}
}
+131
View File
@@ -0,0 +1,131 @@
import { describe, expect, it } from "vitest";
import { join, resolve } from "node:path";
import {
bootstrapSidecarRuntime,
createSidecarLaunchEnv,
resolveAppIpcPath,
resolveAppRuntimePath,
resolveNamespace,
resolveNamespaceRoot,
resolveSidecarBase,
resolveSourceRuntimeRoot,
type SidecarContractDescriptor,
type SidecarStampShape,
} from "./index.js";
type FakeStamp = SidecarStampShape & {
app: "api" | "ui";
mode: "dev" | "prod";
source: "tool" | "pack";
};
const fakeContract: SidecarContractDescriptor<FakeStamp> = {
defaults: {
host: "127.0.0.1",
ipcBase: "/tmp/fake-product/ipc",
namespace: "default",
projectTmpDirName: ".fake-tmp",
windowsPipePrefix: "fake-product",
},
env: {
base: "FAKE_BASE",
ipcBase: "FAKE_IPC_BASE",
ipcPath: "FAKE_IPC_PATH",
namespace: "FAKE_NAMESPACE",
source: "FAKE_SOURCE",
},
normalizeApp(value) {
if (value === "api" || value === "ui") return value;
throw new Error(`unsupported fake app: ${String(value)}`);
},
normalizeNamespace(value) {
if (typeof value !== "string" || !/^[a-z0-9-]+$/.test(value)) {
throw new Error("invalid fake namespace");
}
return value;
},
normalizeSource(value) {
if (value === "tool" || value === "pack") return value;
throw new Error(`unsupported fake source: ${String(value)}`);
},
normalizeStamp(value) {
const stamp = value as Partial<FakeStamp>;
return {
app: this.normalizeApp(stamp.app),
ipc: String(stamp.ipc),
mode: stamp.mode === "prod" ? "prod" : "dev",
namespace: this.normalizeNamespace(stamp.namespace),
source: this.normalizeSource(stamp.source),
};
},
};
describe("generic sidecar path boundary", () => {
it("uses descriptor defaults instead of Open Design constants", () => {
const sourceRoot = resolveSourceRuntimeRoot({
contract: fakeContract,
projectRoot: "/repo/product",
source: "tool",
});
expect(sourceRoot).toBe(resolve("/repo/product", ".fake-tmp", "tool"));
expect(resolveNamespaceRoot({ base: sourceRoot, contract: fakeContract, namespace: "alpha" })).toBe(
join(sourceRoot, "alpha"),
);
expect(
resolveAppRuntimePath({
app: "ui",
contract: fakeContract,
fileName: "cache",
namespaceRoot: join(sourceRoot, "alpha"),
}),
).toBe(join(sourceRoot, "alpha", "ui", "cache"));
});
it("resolves descriptor-specific IPC paths", () => {
expect(resolveAppIpcPath({ app: "ui", contract: fakeContract, namespace: "alpha" })).toBe(
process.platform === "win32" ? "\\\\.\\pipe\\fake-product-alpha-ui" : "/tmp/fake-product/ipc/alpha/ui.sock",
);
});
it("resolves namespace and base from descriptor env names", () => {
const env = {
FAKE_BASE: "/runtime/base",
FAKE_NAMESPACE: "selected",
};
expect(resolveNamespace({ contract: fakeContract, env })).toBe("selected");
expect(resolveSidecarBase({ contract: fakeContract, env, projectRoot: "/repo/product", source: "tool" })).toBe(resolve("/runtime/base"));
});
});
describe("generic sidecar bootstrap", () => {
it("creates and validates launch env from descriptor env names", () => {
const stamp: FakeStamp = {
app: "api",
ipc: resolveAppIpcPath({ app: "api", contract: fakeContract, namespace: "alpha" }),
mode: "dev",
namespace: "alpha",
source: "tool",
};
expect(createSidecarLaunchEnv({ base: "/runtime/base", contract: fakeContract, extraEnv: {}, stamp })).toEqual({
FAKE_BASE: resolve("/runtime/base"),
FAKE_IPC_PATH: stamp.ipc,
FAKE_NAMESPACE: stamp.namespace,
FAKE_SOURCE: stamp.source,
});
expect(
bootstrapSidecarRuntime(stamp, { FAKE_BASE: resolve("/runtime/base") }, { app: "api", contract: fakeContract }),
).toEqual({
app: "api",
base: resolve("/runtime/base"),
ipc: stamp.ipc,
mode: "dev",
namespace: "alpha",
source: "tool",
});
});
});
+566
View File
@@ -0,0 +1,566 @@
import { lstat, mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
import { createConnection, createServer as createNetServer, type Server } from "node:net";
import { dirname, isAbsolute, join, resolve } from "node:path";
export type SidecarStampShape = {
app: string;
ipc: string;
mode: string;
namespace: string;
source: string;
};
export type SidecarContractDescriptor<TStamp extends SidecarStampShape = SidecarStampShape> = {
defaults: {
host: string;
ipcBase: string;
namespace: string;
projectTmpDirName: string;
windowsPipePrefix: string;
};
env: {
base: string;
ipcBase: string;
ipcPath: string;
namespace: string;
source: string;
};
normalizeApp(app: unknown): TStamp["app"];
normalizeNamespace(namespace: unknown): string;
normalizeSource(source: unknown): TStamp["source"];
normalizeStamp(input: unknown): TStamp;
};
export type NamespaceResolutionOptions<TStamp extends SidecarStampShape = SidecarStampShape> = {
contract: SidecarContractDescriptor<TStamp>;
env?: NodeJS.ProcessEnv;
namespace?: string | null;
};
export type ProjectRuntimePathRequest<TStamp extends SidecarStampShape = SidecarStampShape> = {
contract: SidecarContractDescriptor<TStamp>;
projectRoot: string;
source: TStamp["source"] | string;
};
export type BaseResolutionOptions<TStamp extends SidecarStampShape = SidecarStampShape> = {
base?: string | null;
contract: SidecarContractDescriptor<TStamp>;
env?: NodeJS.ProcessEnv;
projectRoot?: string;
source: TStamp["source"] | string;
};
export type RuntimePathRequest<TStamp extends SidecarStampShape = SidecarStampShape> = {
base: string;
contract: SidecarContractDescriptor<TStamp>;
namespace: string;
};
export type RuntimeRootRequest<TStamp extends SidecarStampShape = SidecarStampShape> = RuntimePathRequest<TStamp> & {
runId: string;
};
export type AppIpcPathRequest<TStamp extends SidecarStampShape = SidecarStampShape> = {
app: TStamp["app"] | string;
contract: SidecarContractDescriptor<TStamp>;
env?: NodeJS.ProcessEnv;
namespace: string;
};
export type AppRuntimePathRequest<TStamp extends SidecarStampShape = SidecarStampShape> = {
app: TStamp["app"] | string;
contract: SidecarContractDescriptor<TStamp>;
namespaceRoot: string;
};
export type SidecarRuntimeContext<TStamp extends SidecarStampShape = SidecarStampShape> = {
app: TStamp["app"];
base: string;
ipc: string;
mode: TStamp["mode"];
namespace: string;
source: TStamp["source"];
};
export type SidecarLaunchEnvRequest<TStamp extends SidecarStampShape = SidecarStampShape> = {
base: string;
contract: SidecarContractDescriptor<TStamp>;
extraEnv?: NodeJS.ProcessEnv;
stamp: TStamp;
};
export type BootstrapSidecarRuntimeOptions<TStamp extends SidecarStampShape = SidecarStampShape> = {
app: TStamp["app"] | string;
base?: string | null;
contract: SidecarContractDescriptor<TStamp>;
projectRoot?: string;
};
export type PortAllocation = {
port: number;
source: "dynamic" | "forced";
};
export type PortRequest = {
host?: string;
label?: string;
port?: number | string | null;
reserved?: Set<number>;
};
export type JsonIpcHandler = (message: any) => unknown | Promise<unknown>;
export type JsonIpcServerHandle = {
close(): Promise<void>;
};
export function isWindowsNamedPipePath(value: unknown): boolean {
return typeof value === "string" && value.startsWith("\\\\.\\pipe\\");
}
export function normalizeIpcPath(ipc: unknown): string {
if (typeof ipc !== "string") throw new Error("sidecar ipc path must be a string");
if (ipc.length === 0) throw new Error("sidecar ipc path must not be empty");
if (ipc.trim() !== ipc) throw new Error("sidecar ipc path must not contain leading or trailing whitespace");
if (ipc.includes("\0")) throw new Error("sidecar ipc path must not contain null bytes");
if (isWindowsNamedPipePath(ipc)) return ipc;
if (!isAbsolute(ipc)) throw new Error(`sidecar ipc path must be absolute: ${ipc}`);
return ipc;
}
export function resolveNamespace<TStamp extends SidecarStampShape>(options: NamespaceResolutionOptions<TStamp>): string {
return options.contract.normalizeNamespace(
options.namespace ??
options.env?.[options.contract.env.namespace] ??
options.contract.defaults.namespace,
);
}
export function resolveProjectRoot(projectRoot: string): string {
if (typeof projectRoot !== "string" || projectRoot.trim().length === 0) {
throw new Error("projectRoot must be a non-empty string");
}
return resolve(projectRoot);
}
export function resolveProjectTmpRoot<TStamp extends SidecarStampShape>({
contract,
projectRoot,
}: {
contract: SidecarContractDescriptor<TStamp>;
projectRoot: string;
}): string {
return join(resolveProjectRoot(projectRoot), contract.defaults.projectTmpDirName);
}
export function resolveSourceRuntimeRoot<TStamp extends SidecarStampShape>({
contract,
projectRoot,
source,
}: ProjectRuntimePathRequest<TStamp>): string {
return join(resolveProjectTmpRoot({ contract, projectRoot }), contract.normalizeSource(source));
}
export function resolveSidecarBase<TStamp extends SidecarStampShape>({
base,
contract,
env = process.env,
projectRoot = process.cwd(),
source,
}: BaseResolutionOptions<TStamp>): string {
return resolve(base ?? env[contract.env.base] ?? resolveSourceRuntimeRoot({ contract, projectRoot, source }));
}
export function resolveNamespaceRoot<TStamp extends SidecarStampShape>({
base,
contract,
namespace,
}: RuntimePathRequest<TStamp>): string {
return join(resolve(base), contract.normalizeNamespace(namespace));
}
export function resolveRuntimeRoot<TStamp extends SidecarStampShape>({
base,
contract,
namespace,
runId,
}: RuntimeRootRequest<TStamp>): string {
return join(resolveNamespaceRoot({ base, contract, namespace }), "runs", runId);
}
export function resolvePointerPath<TStamp extends SidecarStampShape>({ base, contract, namespace }: RuntimePathRequest<TStamp>): string {
return join(resolveNamespaceRoot({ base, contract, namespace }), "current.json");
}
export function resolveManifestPath({ runtimeRoot }: { runtimeRoot: string }): string {
return join(runtimeRoot, "manifest.json");
}
export function resolveLogsDir<TStamp extends SidecarStampShape>({
app,
contract,
runtimeRoot,
}: {
app: TStamp["app"] | string;
contract: SidecarContractDescriptor<TStamp>;
runtimeRoot: string;
}): string {
return join(runtimeRoot, "logs", contract.normalizeApp(app));
}
export function resolveLogFilePath<TStamp extends SidecarStampShape>({
app,
contract,
fileName = "latest.log",
runtimeRoot,
}: {
app: TStamp["app"] | string;
contract: SidecarContractDescriptor<TStamp>;
fileName?: string;
runtimeRoot: string;
}): string {
return join(resolveLogsDir({ app, contract, runtimeRoot }), fileName);
}
export function resolveAppRuntimeDir<TStamp extends SidecarStampShape>({
app,
contract,
namespaceRoot,
}: AppRuntimePathRequest<TStamp>): string {
return join(namespaceRoot, contract.normalizeApp(app));
}
export function resolveAppRuntimePath<TStamp extends SidecarStampShape>({
app,
contract,
fileName,
namespaceRoot,
}: AppRuntimePathRequest<TStamp> & { fileName: string }): string {
if (fileName.length === 0 || fileName.includes("\0") || /[\\/]/.test(fileName)) {
throw new Error(`app runtime fileName must be a simple path segment: ${fileName}`);
}
return join(resolveAppRuntimeDir({ app, contract, namespaceRoot }), fileName);
}
export function resolveAppIpcPath<TStamp extends SidecarStampShape>({
app,
contract,
env = process.env,
namespace,
}: AppIpcPathRequest<TStamp>): string {
const normalizedApp = contract.normalizeApp(app);
const normalizedNamespace = contract.normalizeNamespace(namespace);
if (process.platform === "win32") {
return `\\\\.\\pipe\\${contract.defaults.windowsPipePrefix}-${normalizedNamespace}-${normalizedApp}`;
}
const ipcBase = resolve(env[contract.env.ipcBase] ?? contract.defaults.ipcBase);
return join(ipcBase, normalizedNamespace, `${normalizedApp}.sock`);
}
export function createSidecarLaunchEnv<TStamp extends SidecarStampShape>({
base,
contract,
extraEnv = process.env,
stamp,
}: SidecarLaunchEnvRequest<TStamp>): NodeJS.ProcessEnv {
const normalizedStamp = contract.normalizeStamp(stamp);
return {
...extraEnv,
[contract.env.base]: resolveSidecarBase({ base, contract, env: extraEnv, source: normalizedStamp.source }),
[contract.env.ipcPath]: normalizedStamp.ipc,
[contract.env.namespace]: normalizedStamp.namespace,
[contract.env.source]: normalizedStamp.source,
};
}
function assertMatchingEnv(env: NodeJS.ProcessEnv, key: string, expected: string): void {
const current = env[key];
if (current != null && current !== expected) {
throw new Error(`sidecar env mismatch for ${key}: expected ${expected}, received ${current}`);
}
}
export function bootstrapSidecarRuntime<TStamp extends SidecarStampShape>(
stampInput: unknown,
env: NodeJS.ProcessEnv,
options: BootstrapSidecarRuntimeOptions<TStamp>,
): SidecarRuntimeContext<TStamp> {
const stamp = options.contract.normalizeStamp(stampInput);
const expectedApp = options.contract.normalizeApp(options.app);
if (stamp.app !== expectedApp) {
throw new Error(`sidecar stamp app mismatch: expected ${expectedApp}, received ${stamp.app}`);
}
const base = resolveSidecarBase({
base: options.base,
contract: options.contract,
env,
projectRoot: options.projectRoot,
source: stamp.source,
});
const ipc = resolveAppIpcPath({ app: stamp.app, contract: options.contract, env, namespace: stamp.namespace });
if (stamp.ipc !== ipc) {
throw new Error(`sidecar ipc path mismatch: expected ${ipc}, received ${stamp.ipc}`);
}
assertMatchingEnv(env, options.contract.env.ipcPath, stamp.ipc);
assertMatchingEnv(env, options.contract.env.namespace, stamp.namespace);
assertMatchingEnv(env, options.contract.env.source, stamp.source);
env[options.contract.env.ipcPath] = ipc;
env[options.contract.env.namespace] = stamp.namespace;
env[options.contract.env.source] = stamp.source;
return {
app: stamp.app,
base,
ipc,
mode: stamp.mode,
namespace: stamp.namespace,
source: stamp.source,
};
}
async function closeServer(server: Server): Promise<void> {
if (!server.listening) return;
await new Promise<void>((resolveClose, rejectClose) => {
server.close((error) => (error == null ? resolveClose() : rejectClose(error)));
});
}
async function listenOnPort(port: number, host: string): Promise<Server> {
const server = createNetServer();
await new Promise<void>((resolveListen, rejectListen) => {
server.once("error", rejectListen);
server.listen({ port, host, exclusive: true }, () => {
server.off("error", rejectListen);
resolveListen();
});
});
return server;
}
function parsePort(value: number | string | null | undefined, label: string): number | null {
if (value == null || value === "") return null;
const port = Number(value);
if (!Number.isInteger(port) || port <= 0 || port > 65535) {
throw new Error(`${label} port must be an integer between 1 and 65535`);
}
return port;
}
function errorCode(error: unknown): string | null {
if (typeof error !== "object" || error == null || !("code" in error)) return null;
const code = (error as { code?: unknown }).code;
return code == null ? null : String(code);
}
function errorMessage(error: unknown): string {
return error instanceof Error ? error.message : String(error);
}
function jsonIpcError(error: unknown): { code?: string; message: string } {
return {
...(errorCode(error) == null ? {} : { code: errorCode(error) as string }),
message: errorMessage(error),
};
}
async function allocateForcedPort(port: number, label: string, host: string, reserved: Set<number>): Promise<PortAllocation> {
if (reserved.has(port)) {
throw new Error(`forced ${label} port ${port} conflicts with another managed port`);
}
let server: Server | null = null;
try {
server = await listenOnPort(port, host);
} catch (error) {
throw new Error(`forced ${label} port ${port} is not available (${errorCode(error) ?? errorMessage(error)})`);
} finally {
if (server) await closeServer(server);
}
reserved.add(port);
return { port, source: "forced" };
}
async function allocateDynamicPort(label: string, host: string, reserved: Set<number>): Promise<PortAllocation> {
for (let attempt = 0; attempt < 20; attempt += 1) {
const server = await listenOnPort(0, host);
const address = server.address();
await closeServer(server);
if (address == null || typeof address === "string") {
throw new Error(`failed to allocate dynamic ${label} port`);
}
if (!reserved.has(address.port)) {
reserved.add(address.port);
return { port: address.port, source: "dynamic" };
}
}
throw new Error(`failed to allocate dynamic ${label} port without conflict`);
}
export async function allocatePort({
host = "127.0.0.1",
label = "runtime",
port,
reserved = new Set<number>(),
}: PortRequest = {}): Promise<PortAllocation> {
const forcedPort = parsePort(port, label);
return forcedPort == null
? await allocateDynamicPort(label, host, reserved)
: await allocateForcedPort(forcedPort, label, host, reserved);
}
export async function readJsonFile<T = any>(filePath: string): Promise<T | null> {
try {
return JSON.parse(await readFile(filePath, "utf8")) as T;
} catch {
return null;
}
}
export async function writeJsonFile(filePath: string, payload: unknown): Promise<void> {
await mkdir(dirname(filePath), { recursive: true });
const tmpPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
await writeFile(tmpPath, `${JSON.stringify(payload, null, 2)}\n`, "utf8");
await rename(tmpPath, filePath);
}
export async function removeFile(filePath: string): Promise<void> {
await rm(filePath, { force: true });
}
export async function removePointerIfCurrent(pointerPath: string, runId: string): Promise<void> {
const pointer = await readJsonFile<{ runId?: string }>(pointerPath);
if (pointer?.runId === runId) await removeFile(pointerPath);
}
async function staleUnixSocketExists(socketPath: string): Promise<boolean> {
try {
const stat = await lstat(socketPath);
if (!stat.isSocket()) return false;
} catch (error) {
if (errorCode(error) === "ENOENT") return false;
throw error;
}
return await new Promise<boolean>((resolveStale, rejectStale) => {
const socket = createConnection(socketPath);
let settled = false;
const settle = (callback: () => void) => {
if (settled) return;
settled = true;
socket.removeAllListeners();
socket.destroy();
callback();
};
socket.once("connect", () => settle(() => resolveStale(false)));
socket.once("error", (error) => {
const code = errorCode(error);
if (code === "ENOENT" || code === "ECONNREFUSED") {
settle(() => resolveStale(true));
return;
}
settle(() => rejectStale(error));
});
});
}
async function prepareIpcPath(socketPath: string): Promise<void> {
if (isWindowsNamedPipePath(socketPath)) return;
await mkdir(dirname(socketPath), { recursive: true });
if (await staleUnixSocketExists(socketPath)) await rm(socketPath, { force: true });
}
export async function createJsonIpcServer({
handler,
socketPath,
}: {
handler: JsonIpcHandler;
socketPath: string;
}): Promise<JsonIpcServerHandle> {
await prepareIpcPath(socketPath);
const server = createNetServer((socket) => {
let buffer = "";
socket.on("error", () => {});
socket.on("data", async (chunk) => {
buffer += chunk.toString();
const newlineIndex = buffer.indexOf("\n");
if (newlineIndex < 0) return;
const frame = buffer.slice(0, newlineIndex);
buffer = buffer.slice(newlineIndex + 1);
try {
const result = await handler(JSON.parse(frame));
socket.end(`${JSON.stringify({ ok: true, result })}\n`);
} catch (error) {
socket.end(
`${JSON.stringify({
ok: false,
error: jsonIpcError(error),
})}\n`,
);
}
});
});
await new Promise<void>((resolveListen, rejectListen) => {
server.once("error", rejectListen);
server.listen(socketPath, () => {
server.off("error", rejectListen);
resolveListen();
});
});
return {
async close() {
await closeServer(server);
if (!isWindowsNamedPipePath(socketPath)) await rm(socketPath, { force: true });
},
};
}
export async function requestJsonIpc<T = any>(
socketPath: string,
payload: unknown,
{ timeoutMs = 1500 }: { timeoutMs?: number } = {},
): Promise<T> {
return await new Promise<T>((resolveRequest, rejectRequest) => {
const socket = createConnection(socketPath);
let settled = false;
let buffer = "";
const settle = (callback: () => void) => {
if (settled) return;
settled = true;
clearTimeout(timeout);
callback();
};
const timeout = setTimeout(() => {
socket.destroy();
settle(() => rejectRequest(new Error(`IPC request timed out: ${socketPath}`)));
}, timeoutMs);
socket.on("connect", () => {
socket.write(`${JSON.stringify(payload)}\n`);
});
socket.on("data", (chunk) => {
buffer += chunk.toString();
const newlineIndex = buffer.indexOf("\n");
if (newlineIndex < 0) return;
socket.end();
settle(() => {
const response = JSON.parse(buffer.slice(0, newlineIndex)) as { error?: { message?: string }; ok: boolean; result?: T };
if (!response.ok) {
rejectRequest(new Error(response.error?.message ?? "IPC request failed"));
return;
}
resolveRequest(response.result as T);
});
});
socket.on("error", (error) => {
settle(() => rejectRequest(error));
});
});
}
+21
View File
@@ -0,0 +1,21 @@
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"declaration": true,
"declarationMap": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": true,
"lib": ["ES2024"],
"module": "NodeNext",
"moduleResolution": "NodeNext",
"outDir": "./dist",
"resolveJsonModule": true,
"rootDir": "./src",
"skipLibCheck": true,
"strict": true,
"target": "ES2024",
"types": ["node"]
},
"include": ["src/**/*.ts"]
}