fix: lazy load bonjour advertiser

This commit is contained in:
Peter Steinberger
2026-05-02 15:05:27 +01:00
parent 408642dc34
commit eddc589ca5
2 changed files with 105 additions and 5 deletions

View File

@@ -0,0 +1,98 @@
import { createTestPluginApi } from "openclaw/plugin-sdk/plugin-test-api";
import { describe, expect, it, vi } from "vitest";
const mocks = vi.hoisted(() => ({
advertiserModuleLoaded: vi.fn(),
runtimeModuleLoaded: vi.fn(),
startGatewayBonjourAdvertiser: vi.fn(async () => ({ stop: vi.fn() })),
registerUncaughtExceptionHandler: vi.fn(),
registerUnhandledRejectionHandler: vi.fn(),
}));
vi.mock("./src/advertiser.js", () => {
mocks.advertiserModuleLoaded();
return {
startGatewayBonjourAdvertiser: mocks.startGatewayBonjourAdvertiser,
};
});
vi.mock("openclaw/plugin-sdk/runtime", () => {
mocks.runtimeModuleLoaded();
return {
registerUncaughtExceptionHandler: mocks.registerUncaughtExceptionHandler,
registerUnhandledRejectionHandler: mocks.registerUnhandledRejectionHandler,
};
});
const { default: bonjourPlugin } = await import("./index.js");
describe("bonjour plugin entry", () => {
it("lazy-loads advertiser runtime when gateway discovery advertises", async () => {
let discoveryService:
| Parameters<ReturnType<typeof createTestPluginApi>["registerGatewayDiscoveryService"]>[0]
| undefined;
const logger = {
info: vi.fn(),
warn: vi.fn(),
error: vi.fn(),
debug: vi.fn(),
};
const api = createTestPluginApi({
logger,
registerGatewayDiscoveryService(service) {
discoveryService = service;
},
});
expect(mocks.advertiserModuleLoaded).not.toHaveBeenCalled();
expect(mocks.runtimeModuleLoaded).not.toHaveBeenCalled();
bonjourPlugin.register(api);
expect(discoveryService?.id).toBe("bonjour");
expect(mocks.advertiserModuleLoaded).not.toHaveBeenCalled();
expect(mocks.runtimeModuleLoaded).not.toHaveBeenCalled();
if (!discoveryService) {
throw new Error("expected bonjour plugin to register a discovery service");
}
const stop = vi.fn();
mocks.startGatewayBonjourAdvertiser.mockResolvedValueOnce({ stop });
await expect(
discoveryService.advertise({
machineDisplayName: "Dev Box",
gatewayPort: 3210,
gatewayTlsEnabled: true,
gatewayTlsFingerprintSha256: "abc123",
canvasPort: 9876,
sshPort: 22,
tailnetDns: "dev.tailnet.ts.net",
cliPath: "/usr/local/bin/openclaw",
minimal: false,
}),
).resolves.toEqual({ stop });
expect(mocks.advertiserModuleLoaded).toHaveBeenCalledTimes(1);
expect(mocks.runtimeModuleLoaded).toHaveBeenCalledTimes(1);
expect(mocks.startGatewayBonjourAdvertiser).toHaveBeenCalledWith(
{
instanceName: "Dev Box (OpenClaw)",
gatewayPort: 3210,
gatewayTlsEnabled: true,
gatewayTlsFingerprintSha256: "abc123",
canvasPort: 9876,
sshPort: 22,
tailnetDns: "dev.tailnet.ts.net",
cliPath: "/usr/local/bin/openclaw",
minimal: false,
},
{
logger,
registerUncaughtExceptionHandler: mocks.registerUncaughtExceptionHandler,
registerUnhandledRejectionHandler: mocks.registerUnhandledRejectionHandler,
},
);
});
});

View File

@@ -1,9 +1,4 @@
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
import {
registerUncaughtExceptionHandler,
registerUnhandledRejectionHandler,
} from "openclaw/plugin-sdk/runtime";
import { startGatewayBonjourAdvertiser } from "./src/advertiser.js";
function formatBonjourInstanceName(displayName: string) {
const trimmed = displayName.trim();
@@ -24,6 +19,13 @@ export default definePluginEntry({
api.registerGatewayDiscoveryService({
id: "bonjour",
advertise: async (ctx) => {
const [
{ startGatewayBonjourAdvertiser },
{ registerUncaughtExceptionHandler, registerUnhandledRejectionHandler },
] = await Promise.all([
import("./src/advertiser.js"),
import("openclaw/plugin-sdk/runtime"),
]);
const advertiser = await startGatewayBonjourAdvertiser(
{
instanceName: formatBonjourInstanceName(ctx.machineDisplayName),