From 805481c176bb0fc78895a25fdda84722ed168d6c Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sun, 19 Apr 2026 02:03:07 +0100 Subject: [PATCH] perf: narrow bonjour and sqlite runtime type surfaces --- .../memory-host-sdk/src/host/sqlite-vec.ts | 13 +++++- src/infra/bonjour.ts | 46 ++++++++++++++----- src/memory-host-sdk/host/sqlite-vec.ts | 12 +++-- 3 files changed, 56 insertions(+), 15 deletions(-) diff --git a/packages/memory-host-sdk/src/host/sqlite-vec.ts b/packages/memory-host-sdk/src/host/sqlite-vec.ts index b0cf3672f49..e7926b936ba 100644 --- a/packages/memory-host-sdk/src/host/sqlite-vec.ts +++ b/packages/memory-host-sdk/src/host/sqlite-vec.ts @@ -2,12 +2,23 @@ import type { DatabaseSync } from "node:sqlite"; import { formatErrorMessage } from "../../../../src/infra/errors.js"; import { normalizeOptionalString } from "../../../../src/shared/string-coerce.js"; +type SqliteVecModule = { + getLoadablePath: () => string; + load: (db: DatabaseSync) => void; +}; + +const SQLITE_VEC_MODULE_ID = "sqlite-vec"; + +async function loadSqliteVecModule(): Promise { + return import(SQLITE_VEC_MODULE_ID) as Promise; +} + export async function loadSqliteVecExtension(params: { db: DatabaseSync; extensionPath?: string; }): Promise<{ ok: boolean; extensionPath?: string; error?: string }> { try { - const sqliteVec = await import("sqlite-vec"); + const sqliteVec = await loadSqliteVecModule(); const resolvedPath = normalizeOptionalString(params.extensionPath); const extensionPath = resolvedPath ?? sqliteVec.getLoadablePath(); diff --git a/src/infra/bonjour.ts b/src/infra/bonjour.ts index 51e0c532cd2..51bc46b50ec 100644 --- a/src/infra/bonjour.ts +++ b/src/infra/bonjour.ts @@ -48,9 +48,33 @@ function prettifyInstanceName(name: string) { return normalized.replace(/\s+\(OpenClaw\)\s*$/i, "").trim() || normalized; } -type BonjourService = import("@homebridge/ciao").CiaoService; -type BonjourResponder = import("@homebridge/ciao").Responder; -type BonjourServiceState = BonjourService["serviceState"]; +type BonjourService = { + serviceState?: unknown; + advertise: () => Promise; + destroy: () => Promise; + getFQDN: () => string; + getHostname: () => string; + getPort: () => number; + on: (event: "name-change" | "hostname-change", listener: (value: unknown) => void) => unknown; +}; + +type BonjourResponder = { + createService: (options: { + name: string; + type: string; + protocol: unknown; + port: number; + domain: string; + hostname: string; + txt: Record; + }) => BonjourService; + shutdown: () => Promise; +}; + +type CiaoModule = { + getResponder: () => BonjourResponder; + Protocol: { TCP: unknown }; +}; type BonjourCycle = { responder: BonjourResponder; @@ -59,7 +83,7 @@ type BonjourCycle = { }; type ServiceStateTracker = { - state: BonjourServiceState | "unknown"; + state: string; sinceMs: number; }; @@ -68,7 +92,7 @@ type ConsoleLogFn = (...args: unknown[]) => void; const WATCHDOG_INTERVAL_MS = 5_000; const REPAIR_DEBOUNCE_MS = 30_000; const STUCK_ANNOUNCING_MS = 8_000; -const BONJOUR_ANNOUNCED_STATE = "announced" as BonjourServiceState; +const BONJOUR_ANNOUNCED_STATE = "announced"; const CIAO_SELF_PROBE_RETRY_FRAGMENT = "failed probing with reason: Error: Can't probe for a service which is announced already."; @@ -95,7 +119,7 @@ function serviceSummary(label: string, svc: BonjourService): string { return `${label} fqdn=${fqdn} host=${hostname} port=${port} state=${state}`; } -function isAnnouncedState(state: BonjourServiceState | "unknown") { +function isAnnouncedState(state: string) { return state === BONJOUR_ANNOUNCED_STATE; } @@ -136,10 +160,11 @@ function installCiaoConsoleNoiseFilter(): () => void { }; } -let ciaoModulePromise: Promise | null = null; +const CIAO_MODULE_ID = "@homebridge/ciao"; +let ciaoModulePromise: Promise | null = null; -async function loadCiaoModule(): Promise { - ciaoModulePromise ??= import("@homebridge/ciao"); +async function loadCiaoModule(): Promise { + ciaoModulePromise ??= import(CIAO_MODULE_ID) as Promise; return ciaoModulePromise; } @@ -319,8 +344,7 @@ export async function startGatewayBonjourAdvertiser( const updateStateTrackers = (services: Array<{ label: string; svc: BonjourService }>) => { const now = Date.now(); for (const { label, svc } of services) { - const nextState: BonjourServiceState | "unknown" = - typeof svc.serviceState === "string" ? svc.serviceState : "unknown"; + const nextState = typeof svc.serviceState === "string" ? svc.serviceState : "unknown"; const current = stateTracker.get(label); const nextEnteredAt = current && !isAnnouncedState(current.state) && !isAnnouncedState(nextState) diff --git a/src/memory-host-sdk/host/sqlite-vec.ts b/src/memory-host-sdk/host/sqlite-vec.ts index 67294a17ef1..cd7443af38c 100644 --- a/src/memory-host-sdk/host/sqlite-vec.ts +++ b/src/memory-host-sdk/host/sqlite-vec.ts @@ -2,10 +2,16 @@ import type { DatabaseSync } from "node:sqlite"; import { formatErrorMessage } from "../../infra/errors.js"; import { normalizeOptionalString } from "../../shared/string-coerce.js"; -let sqliteVecModulePromise: Promise | null = null; +type SqliteVecModule = { + getLoadablePath: () => string; + load: (db: DatabaseSync) => void; +}; -async function loadSqliteVecModule(): Promise { - sqliteVecModulePromise ??= import("sqlite-vec"); +const SQLITE_VEC_MODULE_ID = "sqlite-vec"; +let sqliteVecModulePromise: Promise | null = null; + +async function loadSqliteVecModule(): Promise { + sqliteVecModulePromise ??= import(SQLITE_VEC_MODULE_ID) as Promise; return sqliteVecModulePromise; }