feat(companion): add reconnect resilience
This commit is contained in:
@@ -7,13 +7,14 @@ const {
|
||||
mockRuntimeCtorArgs,
|
||||
mockRuntimeInstances,
|
||||
} = vi.hoisted(() => {
|
||||
const runtimeCtorArgs: Array<{ url: string; token?: string }> = [];
|
||||
const runtimeCtorArgs: Array<{ url: string; token?: string; autoReconnect?: boolean }> = [];
|
||||
const runtimeInstances: Array<{
|
||||
connect: ReturnType<typeof vi.fn>;
|
||||
registerNode: ReturnType<typeof vi.fn>;
|
||||
setNodeStatus: ReturnType<typeof vi.fn>;
|
||||
subscribeAgentStream: ReturnType<typeof vi.fn>;
|
||||
subscribeAgentTyping: ReturnType<typeof vi.fn>;
|
||||
subscribeConnectionEvents: ReturnType<typeof vi.fn>;
|
||||
disconnect: ReturnType<typeof vi.fn>;
|
||||
}> = [];
|
||||
|
||||
@@ -43,7 +44,13 @@ vi.mock('./shared.js', () => ({
|
||||
|
||||
vi.mock('../companion/index.js', () => ({
|
||||
CompanionRuntimeClient: class {
|
||||
connect = vi.fn(async () => undefined);
|
||||
private connectionHandlers: Array<(event: { status: string }) => void> = [];
|
||||
connect = vi.fn(async () => {
|
||||
for (const handler of this.connectionHandlers) {
|
||||
handler({ status: 'connected' });
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
registerNode = vi.fn(async ({ nodeId, role, capabilities }: { nodeId: string; role: string; capabilities: string[] }) => ({
|
||||
registered: true,
|
||||
node: { id: nodeId, role },
|
||||
@@ -53,9 +60,13 @@ vi.mock('../companion/index.js', () => ({
|
||||
setNodeStatus = vi.fn(async () => ({ updated: true, node: { id: 'n', role: 'companion' } }));
|
||||
subscribeAgentStream = vi.fn(() => () => undefined);
|
||||
subscribeAgentTyping = vi.fn(() => () => undefined);
|
||||
subscribeConnectionEvents = vi.fn((handler: (event: { status: string }) => void) => {
|
||||
this.connectionHandlers.push(handler);
|
||||
return () => undefined;
|
||||
});
|
||||
disconnect = vi.fn(() => undefined);
|
||||
|
||||
constructor(opts: { url: string; token?: string }) {
|
||||
constructor(opts: { url: string; token?: string; autoReconnect?: boolean }) {
|
||||
mockRuntimeCtorArgs.push(opts);
|
||||
mockRuntimeInstances.push(this);
|
||||
}
|
||||
@@ -89,7 +100,7 @@ describe('companion command', () => {
|
||||
await program.parseAsync(['node', 'test', 'companion', '--once']);
|
||||
|
||||
expect(mockGetConfigPath).toHaveBeenCalledOnce();
|
||||
expect(mockRuntimeCtorArgs).toEqual([{ url: 'ws://127.0.0.1:18888', token: 'config-token' }]);
|
||||
expect(mockRuntimeCtorArgs).toEqual([{ url: 'ws://127.0.0.1:18888', token: 'config-token', autoReconnect: false }]);
|
||||
expect(mockRuntimeInstances[0]?.connect).toHaveBeenCalledOnce();
|
||||
expect(mockRuntimeInstances[0]?.registerNode).toHaveBeenCalledOnce();
|
||||
expect(mockRuntimeInstances[0]?.setNodeStatus).toHaveBeenCalledOnce();
|
||||
@@ -124,7 +135,7 @@ describe('companion command', () => {
|
||||
'node.push.register',
|
||||
]);
|
||||
|
||||
expect(mockRuntimeCtorArgs).toEqual([{ url: 'ws://10.0.0.5:19000', token: 'override-token' }]);
|
||||
expect(mockRuntimeCtorArgs).toEqual([{ url: 'ws://10.0.0.5:19000', token: 'override-token', autoReconnect: false }]);
|
||||
expect(mockRuntimeInstances[0]?.registerNode).toHaveBeenCalledWith(expect.objectContaining({
|
||||
nodeId: 'test-node',
|
||||
capabilities: ['ui.canvas', 'node.push.register'],
|
||||
@@ -149,4 +160,3 @@ describe('companion command', () => {
|
||||
errSpy.mockRestore();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user