feat: handler
This commit is contained in:
@@ -0,0 +1,96 @@
|
|||||||
|
import { randomUUID } from "node:crypto";
|
||||||
|
import type {
|
||||||
|
ErrorResponse,
|
||||||
|
InstanceSummary,
|
||||||
|
ListRequest,
|
||||||
|
ListResponse,
|
||||||
|
OrchestratorRequest,
|
||||||
|
OrchestratorResponse,
|
||||||
|
SpawnRequest,
|
||||||
|
SpawnResponse,
|
||||||
|
StatusRequest,
|
||||||
|
StatusResponse,
|
||||||
|
StopRequest,
|
||||||
|
StopResponse,
|
||||||
|
} from "./ipc/protocol.ts";
|
||||||
|
import { getInstance, loadInstances, removeInstance, upsertInstance } from "./storage.ts";
|
||||||
|
import type { InstanceRecord } from "./types.ts";
|
||||||
|
|
||||||
|
function toInstanceSummary(instance: InstanceRecord): InstanceSummary {
|
||||||
|
return {
|
||||||
|
id: instance.id,
|
||||||
|
status: instance.status,
|
||||||
|
cwd: instance.cwd,
|
||||||
|
label: instance.label,
|
||||||
|
sessionId: instance.sessionId,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function unknownInstanceError(instanceId: string): ErrorResponse {
|
||||||
|
return {
|
||||||
|
type: "error",
|
||||||
|
ok: false,
|
||||||
|
error: `Unknown instance: ${instanceId}`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overhead types
|
||||||
|
export async function handleIpcRequest(request: SpawnRequest): Promise<SpawnResponse | ErrorResponse>;
|
||||||
|
export async function handleIpcRequest(request: ListRequest): Promise<ListResponse | ErrorResponse>;
|
||||||
|
export async function handleIpcRequest(request: StopRequest): Promise<StopResponse | ErrorResponse>;
|
||||||
|
export async function handleIpcRequest(request: StatusRequest): Promise<StatusResponse | ErrorResponse>;
|
||||||
|
export async function handleIpcRequest(request: OrchestratorRequest): Promise<OrchestratorResponse> {
|
||||||
|
switch (request.type) {
|
||||||
|
case "spawn": {
|
||||||
|
const instance: InstanceRecord = {
|
||||||
|
id: randomUUID(),
|
||||||
|
status: "starting",
|
||||||
|
cwd: request.cwd,
|
||||||
|
createdAt: new Date().toISOString(),
|
||||||
|
lastSeenAt: new Date().toISOString(),
|
||||||
|
label: request.label,
|
||||||
|
};
|
||||||
|
upsertInstance(instance);
|
||||||
|
return {
|
||||||
|
type: "spawn_result",
|
||||||
|
ok: true,
|
||||||
|
instance: toInstanceSummary(instance),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
case "list": {
|
||||||
|
return {
|
||||||
|
type: "list_result",
|
||||||
|
ok: true,
|
||||||
|
instances: loadInstances().map(toInstanceSummary),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
case "status": {
|
||||||
|
const instance = getInstance(request.instanceId);
|
||||||
|
if (!instance) {
|
||||||
|
return unknownInstanceError(request.instanceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: "status_result",
|
||||||
|
ok: true,
|
||||||
|
instance: toInstanceSummary(instance),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
case "stop": {
|
||||||
|
const instance = getInstance(request.instanceId);
|
||||||
|
if (!instance) {
|
||||||
|
return unknownInstanceError(request.instanceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
removeInstance(request.instanceId);
|
||||||
|
return {
|
||||||
|
type: "stop_result",
|
||||||
|
ok: true,
|
||||||
|
instanceId: request.instanceId,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
export * from "./config.ts";
|
export * from "./config.ts";
|
||||||
|
export * from "./handler.ts";
|
||||||
export * from "./ipc/client.ts";
|
export * from "./ipc/client.ts";
|
||||||
export * from "./ipc/protocol.ts";
|
export * from "./ipc/protocol.ts";
|
||||||
export * from "./ipc/server.ts";
|
export * from "./ipc/server.ts";
|
||||||
|
|||||||
@@ -4,12 +4,26 @@ import { getSocketPath } from "../config.ts";
|
|||||||
import {
|
import {
|
||||||
type ErrorResponse,
|
type ErrorResponse,
|
||||||
encodeMessage,
|
encodeMessage,
|
||||||
|
type ListRequest,
|
||||||
|
type ListResponse,
|
||||||
type OrchestratorRequest,
|
type OrchestratorRequest,
|
||||||
|
type OrchestratorResponse,
|
||||||
parseRequestLine,
|
parseRequestLine,
|
||||||
type ResponseFor,
|
type SpawnRequest,
|
||||||
|
type SpawnResponse,
|
||||||
|
type StatusRequest,
|
||||||
|
type StatusResponse,
|
||||||
|
type StopRequest,
|
||||||
|
type StopResponse,
|
||||||
} from "./protocol.ts";
|
} from "./protocol.ts";
|
||||||
|
|
||||||
export type IpcRequestHandler = <T extends OrchestratorRequest>(request: T) => Promise<ResponseFor<T>> | ResponseFor<T>;
|
export interface IpcRequestHandler {
|
||||||
|
(request: SpawnRequest): Promise<SpawnResponse | ErrorResponse> | SpawnResponse | ErrorResponse;
|
||||||
|
(request: ListRequest): Promise<ListResponse | ErrorResponse> | ListResponse | ErrorResponse;
|
||||||
|
(request: StopRequest): Promise<StopResponse | ErrorResponse> | StopResponse | ErrorResponse;
|
||||||
|
(request: StatusRequest): Promise<StatusResponse | ErrorResponse> | StatusResponse | ErrorResponse;
|
||||||
|
(request: OrchestratorRequest): Promise<OrchestratorResponse> | OrchestratorResponse;
|
||||||
|
}
|
||||||
|
|
||||||
export async function startIpcServer(handler: IpcRequestHandler): Promise<Server> {
|
export async function startIpcServer(handler: IpcRequestHandler): Promise<Server> {
|
||||||
const socketPath = getSocketPath();
|
const socketPath = getSocketPath();
|
||||||
|
|||||||
Reference in New Issue
Block a user