Skip to content

Commit a0a44ca

Browse files
committed
fix(studio-bridge): remove dead subscribe/unsubscribe protocol types and codec
The subscribe/unsubscribe mechanism was designed as an opt-in gate for push events (stateChange, logPush) but the plugin sends output and state changes unconditionally — no command ever called subscribeAsync.
1 parent 39ebd78 commit a0a44ca

5 files changed

Lines changed: 8 additions & 204 deletions

File tree

tools/studio-bridge/src/bridge/internal/bridge-client.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -314,11 +314,10 @@ export class BridgeClient extends EventEmitter {
314314
}
315315
// Resolve with a synthetic message (the caller only cares about the list)
316316
pending.resolve({
317-
type: 'subscribeResult',
317+
type: 'heartbeat',
318318
sessionId: '',
319-
requestId: msg.requestId,
320-
payload: { events: [] },
321-
} as PluginMessage);
319+
payload: { uptimeMs: 0, state: 'Edit', pendingRequests: 0 },
320+
});
322321
}
323322
}
324323

tools/studio-bridge/src/server/studio-bridge-server.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -906,17 +906,17 @@ describe('StudioBridgeServer', () => {
906906

907907
const { ws, welcome } = await connectAndRegister(port, sessionId, {
908908
protocolVersion: 2,
909-
capabilities: ['execute', 'queryState', 'subscribe'],
909+
capabilities: ['execute', 'queryState'],
910910
});
911911
client = ws;
912912

913913
await startPromise;
914914

915915
const payload = welcome.payload as Record<string, unknown>;
916916
expect(payload.protocolVersion).toBe(2);
917-
expect(payload.capabilities).toEqual(['execute', 'queryState', 'subscribe']);
917+
expect(payload.capabilities).toEqual(['execute', 'queryState']);
918918
expect(server.protocolVersion).toBe(2);
919-
expect([...server.capabilities]).toEqual(['execute', 'queryState', 'subscribe']);
919+
expect([...server.capabilities]).toEqual(['execute', 'queryState']);
920920
});
921921

922922
it('register message negotiates capabilities to intersection', async () => {

tools/studio-bridge/src/server/studio-bridge-server.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,6 @@ const ACTION_CAPABILITIES: Record<string, Capability> = {
194194
captureScreenshot: 'captureScreenshot',
195195
queryDataModel: 'queryDataModel',
196196
queryLogs: 'queryLogs',
197-
subscribe: 'subscribe',
198-
unsubscribe: 'subscribe',
199197
execute: 'execute',
200198
};
201199

@@ -579,7 +577,6 @@ export class StudioBridgeServer {
579577
'captureScreenshot',
580578
'queryDataModel',
581579
'queryLogs',
582-
'subscribe',
583580
];
584581

585582
if (msg.type === 'hello') {
@@ -694,7 +691,6 @@ export class StudioBridgeServer {
694691
'captureScreenshot',
695692
'queryDataModel',
696693
'queryLogs',
697-
'subscribe',
698694
];
699695

700696
return new Promise<void>((resolve, reject) => {

tools/studio-bridge/src/server/web-socket-protocol-v2.test.ts

Lines changed: 0 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -375,56 +375,6 @@ describe('decodePluginMessage (v2)', () => {
375375
});
376376
});
377377

378-
describe('subscribeResult', () => {
379-
it('decodes a valid subscribeResult', () => {
380-
const msg = roundTripPlugin({
381-
type: 'subscribeResult',
382-
sessionId: 'sess-1',
383-
requestId: 'req-5',
384-
payload: { events: ['stateChange', 'logPush'] },
385-
});
386-
expect(msg).toEqual({
387-
type: 'subscribeResult',
388-
sessionId: 'sess-1',
389-
requestId: 'req-5',
390-
payload: { events: ['stateChange', 'logPush'] },
391-
});
392-
});
393-
394-
it('returns null without requestId', () => {
395-
expect(roundTripPlugin({
396-
type: 'subscribeResult',
397-
sessionId: 'sess-1',
398-
payload: { events: ['stateChange'] },
399-
})).toBeNull();
400-
});
401-
});
402-
403-
describe('unsubscribeResult', () => {
404-
it('decodes a valid unsubscribeResult', () => {
405-
const msg = roundTripPlugin({
406-
type: 'unsubscribeResult',
407-
sessionId: 'sess-1',
408-
requestId: 'req-6',
409-
payload: { events: ['logPush'] },
410-
});
411-
expect(msg).toEqual({
412-
type: 'unsubscribeResult',
413-
sessionId: 'sess-1',
414-
requestId: 'req-6',
415-
payload: { events: ['logPush'] },
416-
});
417-
});
418-
419-
it('returns null without requestId', () => {
420-
expect(roundTripPlugin({
421-
type: 'unsubscribeResult',
422-
sessionId: 'sess-1',
423-
payload: { events: [] },
424-
})).toBeNull();
425-
});
426-
});
427-
428378
describe('error (plugin)', () => {
429379
it('decodes error with requestId', () => {
430380
const msg = roundTripPlugin({
@@ -666,64 +616,6 @@ describe('encodeMessage / decodeServerMessage (v2)', () => {
666616
});
667617
});
668618

669-
describe('subscribe', () => {
670-
it('round-trips subscribe', () => {
671-
const msg: ServerMessage = {
672-
type: 'subscribe',
673-
sessionId: 'sess-1',
674-
requestId: 'req-14',
675-
payload: { events: ['stateChange', 'logPush'] },
676-
};
677-
expect(roundTripServer(msg)).toEqual(msg);
678-
});
679-
680-
it('returns null without requestId', () => {
681-
expect(decodeServerMessage(JSON.stringify({
682-
type: 'subscribe',
683-
sessionId: 'sess-1',
684-
payload: { events: ['stateChange'] },
685-
}))).toBeNull();
686-
});
687-
688-
it('returns null without events array', () => {
689-
expect(decodeServerMessage(JSON.stringify({
690-
type: 'subscribe',
691-
sessionId: 'sess-1',
692-
requestId: 'req-14',
693-
payload: {},
694-
}))).toBeNull();
695-
});
696-
});
697-
698-
describe('unsubscribe', () => {
699-
it('round-trips unsubscribe', () => {
700-
const msg: ServerMessage = {
701-
type: 'unsubscribe',
702-
sessionId: 'sess-1',
703-
requestId: 'req-15',
704-
payload: { events: ['logPush'] },
705-
};
706-
expect(roundTripServer(msg)).toEqual(msg);
707-
});
708-
709-
it('returns null without requestId', () => {
710-
expect(decodeServerMessage(JSON.stringify({
711-
type: 'unsubscribe',
712-
sessionId: 'sess-1',
713-
payload: { events: [] },
714-
}))).toBeNull();
715-
});
716-
717-
it('returns null without events array', () => {
718-
expect(decodeServerMessage(JSON.stringify({
719-
type: 'unsubscribe',
720-
sessionId: 'sess-1',
721-
requestId: 'req-15',
722-
payload: {},
723-
}))).toBeNull();
724-
});
725-
});
726-
727619
describe('error (server)', () => {
728620
it('round-trips error with requestId', () => {
729621
const msg: ServerMessage = {

tools/studio-bridge/src/server/web-socket-protocol.ts

Lines changed: 2 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@
44
*
55
* v1 messages: hello, output, scriptComplete, welcome, execute, shutdown
66
* v2 messages: register, queryState, stateResult, captureScreenshot, screenshotResult,
7-
* queryDataModel, dataModelResult, queryLogs, logsResult, subscribe, subscribeResult,
8-
* unsubscribe, unsubscribeResult, stateChange, heartbeat, error,
9-
* registerAction, registerActionResult
7+
* queryDataModel, dataModelResult, queryLogs, logsResult, stateChange, heartbeat,
8+
* error, registerAction, registerActionResult
109
*/
1110

1211
// ---------------------------------------------------------------------------
@@ -20,15 +19,13 @@ export type OutputLevel = 'Print' | 'Info' | 'Warning' | 'Error';
2019
// ---------------------------------------------------------------------------
2120

2221
export type StudioState = 'Edit' | 'Play' | 'Paused' | 'Run' | 'Server' | 'Client';
23-
export type SubscribableEvent = 'stateChange' | 'logPush';
2422

2523
export type Capability =
2624
| 'execute'
2725
| 'queryState'
2826
| 'captureScreenshot'
2927
| 'queryDataModel'
3028
| 'queryLogs'
31-
| 'subscribe'
3229
| 'heartbeat'
3330
| 'registerAction'
3431
| 'syncActions';
@@ -199,20 +196,6 @@ export interface HeartbeatMessage extends PushMessage {
199196
};
200197
}
201198

202-
export interface SubscribeResultMessage extends RequestMessage {
203-
type: 'subscribeResult';
204-
payload: {
205-
events: SubscribableEvent[];
206-
};
207-
}
208-
209-
export interface UnsubscribeResultMessage extends RequestMessage {
210-
type: 'unsubscribeResult';
211-
payload: {
212-
events: SubscribableEvent[];
213-
};
214-
}
215-
216199
export interface RegisterActionResultMessage extends RequestMessage {
217200
type: 'registerActionResult';
218201
payload: {
@@ -252,8 +235,6 @@ export type PluginMessage =
252235
| LogsResultMessage
253236
| StateChangeMessage
254237
| HeartbeatMessage
255-
| SubscribeResultMessage
256-
| UnsubscribeResultMessage
257238
| RegisterActionResultMessage
258239
| SyncActionsResultMessage
259240
| PluginErrorMessage;
@@ -320,20 +301,6 @@ export interface QueryLogsMessage extends RequestMessage {
320301
};
321302
}
322303

323-
export interface SubscribeMessage extends RequestMessage {
324-
type: 'subscribe';
325-
payload: {
326-
events: SubscribableEvent[];
327-
};
328-
}
329-
330-
export interface UnsubscribeMessage extends RequestMessage {
331-
type: 'unsubscribe';
332-
payload: {
333-
events: SubscribableEvent[];
334-
};
335-
}
336-
337304
export interface RegisterActionMessage extends RequestMessage {
338305
type: 'registerAction';
339306
payload: {
@@ -369,8 +336,6 @@ export type ServerMessage =
369336
| CaptureScreenshotMessage
370337
| QueryDataModelMessage
371338
| QueryLogsMessage
372-
| SubscribeMessage
373-
| UnsubscribeMessage
374339
| RegisterActionMessage
375340
| SyncActionsMessage
376341
| ServerErrorMessage;
@@ -599,30 +564,6 @@ export function decodePluginMessage(raw: string): PluginMessage | null {
599564
},
600565
};
601566

602-
case 'subscribeResult':
603-
if (requestId === undefined) return null;
604-
if (!Array.isArray(payload.events)) return null;
605-
return {
606-
type: 'subscribeResult',
607-
sessionId,
608-
requestId,
609-
payload: {
610-
events: payload.events as SubscribableEvent[],
611-
},
612-
};
613-
614-
case 'unsubscribeResult':
615-
if (requestId === undefined) return null;
616-
if (!Array.isArray(payload.events)) return null;
617-
return {
618-
type: 'unsubscribeResult',
619-
sessionId,
620-
requestId,
621-
payload: {
622-
events: payload.events as SubscribableEvent[],
623-
},
624-
};
625-
626567
case 'registerActionResult':
627568
if (requestId === undefined) return null;
628569
if (typeof payload.name !== 'string' || typeof payload.success !== 'boolean') return null;
@@ -765,30 +706,6 @@ export function decodeServerMessage(raw: string): ServerMessage | null {
765706
},
766707
};
767708

768-
case 'subscribe':
769-
if (requestId === undefined) return null;
770-
if (!Array.isArray(payload.events)) return null;
771-
return {
772-
type: 'subscribe',
773-
sessionId,
774-
requestId,
775-
payload: {
776-
events: payload.events as SubscribableEvent[],
777-
},
778-
};
779-
780-
case 'unsubscribe':
781-
if (requestId === undefined) return null;
782-
if (!Array.isArray(payload.events)) return null;
783-
return {
784-
type: 'unsubscribe',
785-
sessionId,
786-
requestId,
787-
payload: {
788-
events: payload.events as SubscribableEvent[],
789-
},
790-
};
791-
792709
case 'registerAction':
793710
if (requestId === undefined) return null;
794711
if (typeof payload.name !== 'string' || typeof payload.source !== 'string') return null;

0 commit comments

Comments
 (0)