import * as zmq from 'zeromq'; import { pack, unpack } from 'msgpackr'; import { config, PredictorType } from '../config.js'; interface ZeroResponse { code: number; msg: string; data?: any; } export class ZeroClient { private socket: zmq.Request; private address: string; private connected = false; constructor(address: string) { this.address = address; this.socket = new zmq.Request(); this.socket.receiveTimeout = 300000; // 5 minutes timeout this.socket.sendTimeout = 15000; } async connect(): Promise { if (this.connected) return; await this.socket.connect(this.address); this.connected = true; } async request(method: string, args?: any[], kwargs?: Record): Promise { if (!this.connected) { await this.connect(); } const msg: any = { method }; if (args) msg.args = args; if (kwargs) msg.kwargs = kwargs; const packed = pack(msg); await this.socket.send(packed); const [response] = await this.socket.receive(); const result = unpack(response) as ZeroResponse; if (result.code === 0) { return result.data as T; } else { throw new Error(result.msg || 'Predictor request failed'); } } async close(): Promise { if (this.connected) { this.socket.close(); this.connected = false; } } } // Predictor client pool const clients = new Map(); export function getPredictor(type: PredictorType): ZeroClient { if (!clients.has(type)) { const address = config.predictors[type]; clients.set(type, new ZeroClient(address)); } return clients.get(type)!; } export async function closeAllPredictors(): Promise { for (const client of clients.values()) { await client.close(); } clients.clear(); } // High-level predictor functions export interface LayoutResult { detection: { boxes: number[][]; labels: string[]; scores: number[]; }; theta: number; interval: number; sourceSize?: { width: number; height: number; }; } export interface GaugeResult { image: Buffer; } export interface MaskResult { image: Buffer; } export interface SemanticResult { clusters: any[]; } export interface LocResult { boxes: number[][]; scores: number[]; } export interface OcrResult { texts: string[]; scores: number[]; } // Layout: predictDetection([buffer]) export async function predictLayout(imageData: Buffer): Promise { const client = getPredictor('layout'); const results = await client.request('predictDetection', [[imageData]]); return results[0]; } // Gauge: predict([buffer], by_buffer=true) export async function predictGauge(imageData: Buffer): Promise { const client = getPredictor('gauge'); const results = await client.request('predict', [[imageData]], { by_buffer: true }); return results[0]; } // Mask: predict([buffer], by_buffer=true) export async function predictMask(imageData: Buffer): Promise { const client = getPredictor('mask'); const results = await client.request('predict', [[imageData]], { by_buffer: true }); return results[0]; } // Semantic: predict([buffer]) export async function predictSemantic(imageData: Buffer): Promise { const client = getPredictor('semantic'); const results = await client.request('predict', [[imageData]]); return results[0]; } // Loc (text localization): predict([buffer]) export async function predictLoc(imageData: Buffer): Promise { const client = getPredictor('loc'); const results = await client.request('predict', [[imageData]]); return results[0]; } // OCR: predict(buffers=[buffer], location=[...]) export async function predictOcr(imageData: Buffer, locations: any[]): Promise { const client = getPredictor('ocr'); return client.request('predict', [], { buffers: [imageData], location: locations }); } // Brackets: predict(buffers=[buffer]) export async function predictBrackets(imageData: Buffer): Promise { const client = getPredictor('brackets'); return client.request('predict', [], { buffers: [imageData] }); }