feat(companion): support runtime client autoConnect mode
This commit is contained in:
@@ -268,4 +268,31 @@ describe('CompanionRuntimeClient', () => {
|
||||
client.disconnect();
|
||||
}
|
||||
});
|
||||
|
||||
it('supports autoConnect mode for one-shot RPC usage', async () => {
|
||||
if (!LISTEN_ALLOWED) {
|
||||
return;
|
||||
}
|
||||
|
||||
const client = new CompanionRuntimeClient({
|
||||
url: `ws://127.0.0.1:${TEST_PORT}`,
|
||||
token: TEST_TOKEN,
|
||||
autoConnect: true,
|
||||
});
|
||||
|
||||
expect(client.connected).toBe(false);
|
||||
|
||||
try {
|
||||
const register = await client.registerNode({
|
||||
nodeId: 'auto-connect-node',
|
||||
role: 'companion',
|
||||
capabilities: ['ui.canvas'],
|
||||
});
|
||||
|
||||
expect(register.registered).toBe(true);
|
||||
expect(client.connected).toBe(true);
|
||||
} finally {
|
||||
client.disconnect();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -37,6 +37,7 @@ export interface CompanionRuntimeClientOptions {
|
||||
url: string;
|
||||
token?: string;
|
||||
requestTimeoutMs?: number;
|
||||
autoConnect?: boolean;
|
||||
websocketFactory?: (url: string) => WebSocket;
|
||||
}
|
||||
|
||||
@@ -249,9 +250,11 @@ export class CompanionRuntimeClient {
|
||||
private readonly url: string;
|
||||
private readonly token?: string;
|
||||
private readonly requestTimeoutMs: number;
|
||||
private readonly autoConnect: boolean;
|
||||
private readonly websocketFactory: (url: string) => WebSocket;
|
||||
|
||||
private ws: WebSocket | null = null;
|
||||
private connectPromise: Promise<void> | null = null;
|
||||
private nextId = 1;
|
||||
private pending = new Map<number, PendingRequest>();
|
||||
|
||||
@@ -259,6 +262,7 @@ export class CompanionRuntimeClient {
|
||||
this.url = options.url;
|
||||
this.token = options.token;
|
||||
this.requestTimeoutMs = options.requestTimeoutMs ?? 15_000;
|
||||
this.autoConnect = options.autoConnect ?? false;
|
||||
this.websocketFactory = options.websocketFactory ?? ((url) => new WebSocket(url));
|
||||
}
|
||||
|
||||
@@ -271,6 +275,19 @@ export class CompanionRuntimeClient {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.connectPromise) {
|
||||
return this.connectPromise;
|
||||
}
|
||||
|
||||
this.connectPromise = this.openConnection();
|
||||
try {
|
||||
await this.connectPromise;
|
||||
} finally {
|
||||
this.connectPromise = null;
|
||||
}
|
||||
}
|
||||
|
||||
private async openConnection(): Promise<void> {
|
||||
const ws = this.websocketFactory(withToken(this.url, this.token));
|
||||
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
@@ -326,6 +343,13 @@ export class CompanionRuntimeClient {
|
||||
}
|
||||
|
||||
async call<T>(method: string, params?: Record<string, unknown>): Promise<T> {
|
||||
if (!this.connected) {
|
||||
if (!this.autoConnect) {
|
||||
throw new Error('WebSocket is not connected');
|
||||
}
|
||||
await this.connect();
|
||||
}
|
||||
|
||||
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
||||
throw new Error('WebSocket is not connected');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user