Wire the CoreDeno sidecar into a fully bidirectional bridge: - Deno→Go (gRPC): Deno connects as CoreService client via polyfilled @grpc/grpc-js over Unix socket. Polyfill patches Deno 2.x http2 gaps (getDefaultSettings, pre-connected socket handling, remoteSettings). - Go→Deno (JSON-RPC): Go connects to Deno's newline-delimited JSON-RPC server for module lifecycle (LoadModule, UnloadModule, ModuleStatus). gRPC server direction avoided due to Deno http2.createServer limitations. - ProcessStart/ProcessStop: gRPC handlers delegate to process.Service with manifest permission gating (run permissions). - Deno runtime: main.ts boots DenoService server, connects CoreService client with retry + health-check round-trip, handles SIGTERM shutdown. 40 unit tests + 2 integration tests (Tier 1 boot + Tier 2 bidirectional). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
50 lines
1.2 KiB
TypeScript
50 lines
1.2 KiB
TypeScript
// Module registry — tracks loaded modules and their lifecycle status.
|
|
// Tier 2: status tracking only. Tier 3 adds real Deno worker isolates.
|
|
|
|
export type ModuleStatus = "UNKNOWN" | "LOADING" | "RUNNING" | "STOPPED" | "ERRORED";
|
|
|
|
// Status enum values matching the proto definition.
|
|
export const StatusEnum: Record<ModuleStatus, number> = {
|
|
UNKNOWN: 0,
|
|
LOADING: 1,
|
|
RUNNING: 2,
|
|
STOPPED: 3,
|
|
ERRORED: 4,
|
|
};
|
|
|
|
export interface Module {
|
|
code: string;
|
|
entryPoint: string;
|
|
permissions: string[];
|
|
status: ModuleStatus;
|
|
}
|
|
|
|
export class ModuleRegistry {
|
|
private modules = new Map<string, Module>();
|
|
|
|
load(code: string, entryPoint: string, permissions: string[]): void {
|
|
this.modules.set(code, {
|
|
code,
|
|
entryPoint,
|
|
permissions,
|
|
status: "RUNNING",
|
|
});
|
|
console.error(`CoreDeno: module loaded: ${code}`);
|
|
}
|
|
|
|
unload(code: string): boolean {
|
|
const mod = this.modules.get(code);
|
|
if (!mod) return false;
|
|
mod.status = "STOPPED";
|
|
console.error(`CoreDeno: module unloaded: ${code}`);
|
|
return true;
|
|
}
|
|
|
|
status(code: string): ModuleStatus {
|
|
return this.modules.get(code)?.status ?? "UNKNOWN";
|
|
}
|
|
|
|
list(): Module[] {
|
|
return Array.from(this.modules.values());
|
|
}
|
|
}
|