Skip to content

Commit 9bb8b7d

Browse files
committed
feat(shared): add compression field to attach/attached protocol types
Add optional compression?: 'deflate' to AttachRequest and AttachedEvent interfaces. Add string type validation for the compression field in codec validateFields() for both attach and attached message types. Includes 8 new codec tests for round-trip and validation.
1 parent 81b58b3 commit 9bb8b7d

3 files changed

Lines changed: 64 additions & 0 deletions

File tree

src/__tests__/codec.test.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,24 @@ describe('HostRequest round-trip', () => {
7474
expect(result).toEqual(msg);
7575
});
7676

77+
it('encodes/decodes attach with compression', () => {
78+
const msg: HostRequest = { type: 'attach', paneId: '%1', cols: 80, rows: 24, compression: 'deflate' };
79+
const result = roundTrip(msg);
80+
expect(result).toEqual(msg);
81+
if (result.type === 'attach') {
82+
expect(result.compression).toBe('deflate');
83+
}
84+
});
85+
86+
it('encodes/decodes attach without compression (field absent)', () => {
87+
const msg: HostRequest = { type: 'attach', paneId: '%1', cols: 80, rows: 24 };
88+
const result = roundTrip(msg);
89+
expect(result).toEqual(msg);
90+
if (result.type === 'attach') {
91+
expect(result.compression).toBeUndefined();
92+
}
93+
});
94+
7795
it('encodes/decodes detach', () => {
7896
const msg: HostRequest = { type: 'detach' };
7997
const result = roundTrip(msg);
@@ -166,6 +184,24 @@ describe('HostEvent round-trip', () => {
166184
expect(result).toEqual(msg);
167185
});
168186

187+
it('encodes/decodes attached with compression', () => {
188+
const msg: HostEvent = { type: 'attached', paneId: '%1', compression: 'deflate' };
189+
const result = roundTrip(msg);
190+
expect(result).toEqual(msg);
191+
if (result.type === 'attached') {
192+
expect(result.compression).toBe('deflate');
193+
}
194+
});
195+
196+
it('encodes/decodes attached without compression (field absent)', () => {
197+
const msg: HostEvent = { type: 'attached', paneId: '%1' };
198+
const result = roundTrip(msg);
199+
expect(result).toEqual(msg);
200+
if (result.type === 'attached') {
201+
expect(result.compression).toBeUndefined();
202+
}
203+
});
204+
169205
it('encodes/decodes detached', () => {
170206
const msg: HostEvent = { type: 'detached' };
171207
const result = roundTrip(msg);
@@ -367,6 +403,16 @@ describe('decode structural validation', () => {
367403
expect(() => decodeMalformed({ type: 'attach', paneId: '%1', cols: 80, rows: Infinity }))
368404
.toThrow('attach: "rows" must be a finite number');
369405
});
406+
407+
it('accepts valid compression string', () => {
408+
expect(() => decodeMalformed({ type: 'attach', paneId: '%1', cols: 80, rows: 24, compression: 'deflate' }))
409+
.not.toThrow();
410+
});
411+
412+
it('rejects non-string compression', () => {
413+
expect(() => decodeMalformed({ type: 'attach', paneId: '%1', cols: 80, rows: 24, compression: 123 }))
414+
.toThrow('attach: "compression" must be a string');
415+
});
370416
});
371417

372418
describe('input', () => {
@@ -441,6 +487,16 @@ describe('decode structural validation', () => {
441487
expect(() => decodeMalformed({ type: 'attached' }))
442488
.toThrow('attached: "paneId" must be a string');
443489
});
490+
491+
it('accepts valid compression string', () => {
492+
expect(() => decodeMalformed({ type: 'attached', paneId: '%1', compression: 'deflate' }))
493+
.not.toThrow();
494+
});
495+
496+
it('rejects non-string compression', () => {
497+
expect(() => decodeMalformed({ type: 'attached', paneId: '%1', compression: 123 }))
498+
.toThrow('attached: "compression" must be a string');
499+
});
444500
});
445501

446502
describe('session_ended', () => {

src/codec.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ function validateFields(msg: Record<string, unknown>): void {
8989
if ('reattach' in msg && typeof msg['reattach'] !== 'boolean') {
9090
throw new Error('attach: "reattach" must be a boolean');
9191
}
92+
if ('compression' in msg && typeof msg['compression'] !== 'string') {
93+
throw new Error('attach: "compression" must be a string');
94+
}
9295
break;
9396

9497
case 'input':
@@ -118,6 +121,9 @@ function validateFields(msg: Record<string, unknown>): void {
118121

119122
case 'attached':
120123
assertString(msg, 'attached', 'paneId');
124+
if ('compression' in msg && typeof msg['compression'] !== 'string') {
125+
throw new Error('attached: "compression" must be a string');
126+
}
121127
break;
122128

123129
case 'session_ended':

src/protocol.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export interface AttachRequest {
1818
cols: number;
1919
rows: number;
2020
reattach?: boolean;
21+
compression?: 'deflate';
2122
}
2223

2324
export interface DetachRequest {
@@ -68,6 +69,7 @@ export interface OutputEvent {
6869
export interface AttachedEvent {
6970
type: 'attached';
7071
paneId: string;
72+
compression?: 'deflate';
7173
}
7274

7375
export interface DetachedEvent {

0 commit comments

Comments
 (0)