Skip to content

Commit fbc135f

Browse files
committed
feat: 🎸 move compact encoding routines to the ecnoder module
1 parent ad52bd9 commit fbc135f

File tree

3 files changed

+117
-137
lines changed

3 files changed

+117
-137
lines changed

src/common/codec/compact/CompactRpcMessageCodec.ts

Lines changed: 117 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,29 +51,141 @@ const fromJson = (arr: unknown | unknown[] | types.CompactMessage): msg.Reactive
5151
throw RpcError.value(RpcError.validation('Unknown message type'));
5252
};
5353

54+
const encodeCompactWithNameAndPayload = (
55+
codec: JsonValueCodec,
56+
type: CompactMessageType,
57+
msg: msg.RequestDataMessage | msg.RequestCompleteMessage | msg.RequestErrorMessage,
58+
) => {
59+
const encoder = codec.encoder;
60+
if (encoder instanceof CborEncoder || encoder instanceof MsgPackEncoder) {
61+
const value = msg.value;
62+
const hasValue = value !== undefined;
63+
encoder.writeArrHdr(hasValue ? 4 : 3);
64+
encoder.writeUInteger(type);
65+
encoder.writeUInteger(msg.id);
66+
encoder.writeAsciiStr(msg.method);
67+
if (hasValue) {
68+
if (value.type) value.type.encoder(codec.format)(value.data, encoder);
69+
else encoder.writeAny(value.data);
70+
}
71+
} else if (encoder instanceof JsonEncoder) {
72+
const value = msg.value;
73+
encoder.writeStartArr();
74+
encoder.writeNumber(type);
75+
encoder.writeArrSeparator();
76+
encoder.writeNumber(msg.id);
77+
encoder.writeArrSeparator();
78+
encoder.writeAsciiStr(msg.method);
79+
const hasValue = value !== undefined;
80+
if (hasValue) {
81+
encoder.writeArrSeparator();
82+
if (value.type) value.type.encoder(codec.format)(value.data, encoder);
83+
else encoder.writeAny(value.data);
84+
}
85+
encoder.writeEndArr();
86+
} else encoder.writeArr(msg.toCompact());
87+
};
88+
89+
const encodeCompactWithPayload = (
90+
codec: JsonValueCodec,
91+
type: CompactMessageType,
92+
msg: msg.ResponseCompleteMessage | msg.ResponseDataMessage | msg.ResponseErrorMessage,
93+
) => {
94+
const encoder = codec.encoder;
95+
if (encoder instanceof CborEncoder || encoder instanceof MsgPackEncoder) {
96+
const value = msg.value;
97+
const hasValue = value !== undefined;
98+
encoder.writeArrHdr(hasValue ? 3 : 2);
99+
encoder.writeUInteger(type);
100+
encoder.writeUInteger(msg.id);
101+
if (hasValue) {
102+
if (value.type) {
103+
value.type.encoder(codec.format)(value.data, encoder);
104+
} else encoder.writeAny(value.data);
105+
}
106+
} else if (encoder instanceof JsonEncoder) {
107+
const value = msg.value;
108+
encoder.writeStartArr();
109+
encoder.writeNumber(type);
110+
encoder.writeArrSeparator();
111+
encoder.writeNumber(msg.id);
112+
const hasValue = value !== undefined;
113+
if (hasValue) {
114+
encoder.writeArrSeparator();
115+
if (value.type) value.type.encoder(codec.format)(value.data, encoder);
116+
else encoder.writeAny(value.data);
117+
}
118+
encoder.writeEndArr();
119+
} else encoder.writeArr(msg.toCompact());
120+
};
121+
54122
export class CompactRpcMessageCodec implements RpcMessageCodec {
55123
id = 'rx.compact';
56124
format = RpcMessageFormat.Compact;
57125

58-
public encodeMessage(jsonCodec: JsonValueCodec, message: msg.ReactiveRpcMessage): void {
59-
message.encodeCompact(jsonCodec);
126+
public encodeMessage(codec: JsonValueCodec, message: msg.ReactiveRpcMessage): void {
127+
if (message instanceof msg.NotificationMessage) {
128+
const encoder = codec.encoder;
129+
if (encoder instanceof CborEncoder || encoder instanceof MsgPackEncoder) {
130+
const value = message.value;
131+
const hasValue = value !== undefined;
132+
encoder.writeArrHdr(hasValue ? 3 : 2);
133+
encoder.writeUInteger(CompactMessageType.Notification);
134+
encoder.writeAsciiStr(message.method);
135+
if (hasValue) {
136+
if (value.type) value.type.encoder(codec.format)(value.data, encoder);
137+
else encoder.writeAny(value.data);
138+
}
139+
} else if (encoder instanceof JsonEncoder) {
140+
const value = message.value;
141+
encoder.writeStartArr();
142+
encoder.writeNumber(CompactMessageType.Notification);
143+
encoder.writeArrSeparator();
144+
encoder.writeAsciiStr(message.method);
145+
const hasValue = value !== undefined;
146+
if (hasValue) {
147+
encoder.writeArrSeparator();
148+
if (value.type) value.type.encoder(codec.format)(value.data, encoder);
149+
else encoder.writeAny(value.data);
150+
}
151+
encoder.writeEndArr();
152+
} else encoder.writeArr(message.toCompact());
153+
} else if (message instanceof msg.RequestDataMessage) {
154+
encodeCompactWithNameAndPayload(codec, CompactMessageType.RequestData, message);
155+
} else if (message instanceof msg.RequestCompleteMessage) {
156+
encodeCompactWithNameAndPayload(codec, CompactMessageType.RequestComplete, message);
157+
} else if (message instanceof msg.RequestErrorMessage) {
158+
encodeCompactWithNameAndPayload(codec, CompactMessageType.RequestError, message);
159+
} else if (message instanceof msg.RequestUnsubscribeMessage) {
160+
codec.encoder.writeArr(message.toCompact());
161+
} else if (message instanceof msg.ResponseCompleteMessage) {
162+
encodeCompactWithPayload(codec, CompactMessageType.ResponseComplete, message);
163+
} else if (message instanceof msg.ResponseDataMessage) {
164+
encodeCompactWithPayload(codec, CompactMessageType.ResponseData, message);
165+
} else if (message instanceof msg.ResponseErrorMessage) {
166+
encodeCompactWithPayload(codec, CompactMessageType.ResponseError, message);
167+
} else if (message instanceof msg.ResponseUnsubscribeMessage) {
168+
codec.encoder.writeArr(message.toCompact());
169+
} else {
170+
codec.encoder.writeArr((message as any).toCompact());
171+
}
60172
}
61173

62174
public encodeBatch(jsonCodec: JsonValueCodec, batch: msg.ReactiveRpcMessage[]): void {
63175
const encoder = jsonCodec.encoder;
64176
if (encoder instanceof CborEncoder || encoder instanceof MsgPackEncoder) {
65177
const length = batch.length;
66178
encoder.writeArrHdr(length);
67-
for (let i = 0; i < length; i++) batch[i].encodeCompact(jsonCodec);
179+
for (let i = 0; i < length; i++) this.encodeMessage(jsonCodec, batch[i]);
68180
} else if (encoder instanceof JsonEncoder) {
69181
const length = batch.length;
70182
const last = length - 1;
71183
encoder.writeStartArr();
72184
for (let i = 0; i < last; i++) {
73-
batch[i].encodeCompact(jsonCodec);
185+
this.encodeMessage(jsonCodec, batch[i]);
74186
encoder.writeArrSeparator();
75187
}
76-
if (length > 0) batch[last].encodeCompact(jsonCodec);
188+
if (length > 0) this.encodeMessage(jsonCodec, batch[last]);
77189
encoder.writeEndArr();
78190
} else {
79191
const jsonMessages: types.CompactMessage[] = [];

src/common/messages/messages.ts

Lines changed: 0 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
import {MsgPackEncoder} from '@jsonjoy.com/json-pack/lib/msgpack'; // TODO: Should not statically import codecs
2-
import {CborEncoder} from '@jsonjoy.com/json-pack/lib/cbor/CborEncoder'; // TODO: Should not statically import codecs
3-
import {JsonEncoder} from '@jsonjoy.com/json-pack/lib/json/JsonEncoder'; // TODO: Should not statically import codecs
41
import {BinaryMessageType} from '../codec/binary/constants';
52
import {CompactMessageType} from '../codec/compact/constants';
63
import {validateId, validateMethod} from '../rpc/validation';
@@ -77,74 +74,6 @@ const encodeBinaryWithPayload = (
7774
encodeHeader(writer, typeU16, id, payloadSize, start);
7875
};
7976

80-
const encodeCompactWithNameAndPayload = (
81-
codec: JsonValueCodec,
82-
type: CompactMessageType,
83-
msg: RequestDataMessage | RequestCompleteMessage | RequestErrorMessage,
84-
) => {
85-
const encoder = codec.encoder;
86-
if (encoder instanceof CborEncoder || encoder instanceof MsgPackEncoder) {
87-
const value = msg.value;
88-
const hasValue = value !== undefined;
89-
encoder.writeArrHdr(hasValue ? 4 : 3);
90-
encoder.writeUInteger(type);
91-
encoder.writeUInteger(msg.id);
92-
encoder.writeAsciiStr(msg.method);
93-
if (hasValue) {
94-
if (value.type) value.type.encoder(codec.format)(value.data, encoder);
95-
else encoder.writeAny(value.data);
96-
}
97-
} else if (encoder instanceof JsonEncoder) {
98-
const value = msg.value;
99-
encoder.writeStartArr();
100-
encoder.writeNumber(type);
101-
encoder.writeArrSeparator();
102-
encoder.writeNumber(msg.id);
103-
encoder.writeArrSeparator();
104-
encoder.writeAsciiStr(msg.method);
105-
const hasValue = value !== undefined;
106-
if (hasValue) {
107-
encoder.writeArrSeparator();
108-
if (value.type) value.type.encoder(codec.format)(value.data, encoder);
109-
else encoder.writeAny(value.data);
110-
}
111-
encoder.writeEndArr();
112-
} else encoder.writeArr(msg.toCompact());
113-
};
114-
115-
const encodeCompactWithPayload = (
116-
codec: JsonValueCodec,
117-
type: CompactMessageType,
118-
msg: ResponseCompleteMessage | ResponseDataMessage | ResponseErrorMessage,
119-
) => {
120-
const encoder = codec.encoder;
121-
if (encoder instanceof CborEncoder || encoder instanceof MsgPackEncoder) {
122-
const value = msg.value;
123-
const hasValue = value !== undefined;
124-
encoder.writeArrHdr(hasValue ? 3 : 2);
125-
encoder.writeUInteger(type);
126-
encoder.writeUInteger(msg.id);
127-
if (hasValue) {
128-
if (value.type) {
129-
value.type.encoder(codec.format)(value.data, encoder);
130-
} else encoder.writeAny(value.data);
131-
}
132-
} else if (encoder instanceof JsonEncoder) {
133-
const value = msg.value;
134-
encoder.writeStartArr();
135-
encoder.writeNumber(type);
136-
encoder.writeArrSeparator();
137-
encoder.writeNumber(msg.id);
138-
const hasValue = value !== undefined;
139-
if (hasValue) {
140-
encoder.writeArrSeparator();
141-
if (value.type) value.type.encoder(codec.format)(value.data, encoder);
142-
else encoder.writeAny(value.data);
143-
}
144-
encoder.writeEndArr();
145-
} else encoder.writeArr(msg.toCompact());
146-
};
147-
14877
/**
14978
* @category Message
15079
*/
@@ -164,34 +93,6 @@ export class NotificationMessage<V extends RpcValue<any> = RpcValue> implements
16493
: [CompactMessageType.Notification, this.method, this.value.data];
16594
}
16695

167-
public encodeCompact(codec: JsonValueCodec): void {
168-
const encoder = codec.encoder;
169-
if (encoder instanceof CborEncoder || encoder instanceof MsgPackEncoder) {
170-
const value = this.value;
171-
const hasValue = value !== undefined;
172-
encoder.writeArrHdr(hasValue ? 3 : 2);
173-
encoder.writeUInteger(CompactMessageType.Notification);
174-
encoder.writeAsciiStr(this.method);
175-
if (hasValue) {
176-
if (value.type) value.type.encoder(codec.format)(value.data, encoder);
177-
else encoder.writeAny(value.data);
178-
}
179-
} else if (encoder instanceof JsonEncoder) {
180-
const value = this.value;
181-
encoder.writeStartArr();
182-
encoder.writeNumber(CompactMessageType.Notification);
183-
encoder.writeArrSeparator();
184-
encoder.writeAsciiStr(this.method);
185-
const hasValue = value !== undefined;
186-
if (hasValue) {
187-
encoder.writeArrSeparator();
188-
if (value.type) value.type.encoder(codec.format)(value.data, encoder);
189-
else encoder.writeAny(value.data);
190-
}
191-
encoder.writeEndArr();
192-
} else encoder.writeArr(this.toCompact());
193-
}
194-
19596
public encodeBinary(codec: JsonValueCodec): void {
19697
const writer = codec.encoder.writer;
19798
const name = this.method;
@@ -230,10 +131,6 @@ export class RequestDataMessage<V extends RpcValue<any> = RpcValue> implements M
230131
: [CompactMessageType.RequestData, this.id, this.method, this.value.data];
231132
}
232133

233-
public encodeCompact(codec: JsonValueCodec): void {
234-
encodeCompactWithNameAndPayload(codec, CompactMessageType.RequestData, this);
235-
}
236-
237134
public encodeBinary(codec: JsonValueCodec): void {
238135
encodeBinaryWithNameAndPayload(codec, BinaryMessageType.RequestData << 13, this.id, this.method, this.value);
239136
}
@@ -260,10 +157,6 @@ export class RequestCompleteMessage<V extends RpcValue<any> = RpcValue> implemen
260157
: [CompactMessageType.RequestComplete, this.id, this.method, this.value.data];
261158
}
262159

263-
public encodeCompact(codec: JsonValueCodec): void {
264-
encodeCompactWithNameAndPayload(codec, CompactMessageType.RequestComplete, this);
265-
}
266-
267160
public encodeBinary(codec: JsonValueCodec): void {
268161
encodeBinaryWithNameAndPayload(codec, BinaryMessageType.RequestComplete << 13, this.id, this.method, this.value);
269162
}
@@ -288,10 +181,6 @@ export class RequestErrorMessage<V extends RpcValue<any> = RpcValue> implements
288181
return [CompactMessageType.RequestError, this.id, this.method, this.value.data];
289182
}
290183

291-
public encodeCompact(codec: JsonValueCodec): void {
292-
encodeCompactWithNameAndPayload(codec, CompactMessageType.RequestError, this);
293-
}
294-
295184
public encodeBinary(codec: JsonValueCodec): void {
296185
encodeBinaryWithNameAndPayload(codec, BinaryMessageType.RequestError << 13, this.id, this.method, this.value);
297186
}
@@ -311,10 +200,6 @@ export class RequestUnsubscribeMessage implements Message<cmsg.CompactMessage> {
311200
return [CompactMessageType.RequestUnsubscribe, this.id];
312201
}
313202

314-
public encodeCompact(codec: JsonValueCodec): void {
315-
codec.encoder.writeArr(this.toCompact());
316-
}
317-
318203
public encodeBinary(codec: JsonValueCodec): void {
319204
codec.encoder.writer.u32(0b11100000_00000000_00000000_00000000 | this.id);
320205
}
@@ -339,10 +224,6 @@ export class ResponseCompleteMessage<V extends RpcValue<any> = RpcValue> impleme
339224
: [CompactMessageType.ResponseComplete, this.id, this.value.data];
340225
}
341226

342-
public encodeCompact(codec: JsonValueCodec): void {
343-
encodeCompactWithPayload(codec, CompactMessageType.ResponseComplete, this);
344-
}
345-
346227
public encodeBinary(codec: JsonValueCodec): void {
347228
encodeBinaryWithPayload(codec, BinaryMessageType.ResponseComplete << 13, this.id, this.value);
348229
}
@@ -365,10 +246,6 @@ export class ResponseDataMessage<V extends RpcValue<any> = RpcValue> implements
365246
return [CompactMessageType.ResponseData, this.id, this.value.data];
366247
}
367248

368-
public encodeCompact(codec: JsonValueCodec): void {
369-
encodeCompactWithPayload(codec, CompactMessageType.ResponseData, this);
370-
}
371-
372249
public encodeBinary(codec: JsonValueCodec): void {
373250
encodeBinaryWithPayload(codec, BinaryMessageType.ResponseData << 13, this.id, this.value);
374251
}
@@ -391,10 +268,6 @@ export class ResponseErrorMessage<V extends RpcValue<any> = RpcValue> implements
391268
return [CompactMessageType.ResponseError, this.id, this.value.data];
392269
}
393270

394-
public encodeCompact(codec: JsonValueCodec): void {
395-
encodeCompactWithPayload(codec, CompactMessageType.ResponseError, this);
396-
}
397-
398271
public encodeBinary(codec: JsonValueCodec): void {
399272
encodeBinaryWithPayload(codec, BinaryMessageType.ResponseError << 13, this.id, this.value);
400273
}
@@ -414,10 +287,6 @@ export class ResponseUnsubscribeMessage implements Message<cmsg.CompactMessage>
414287
return [CompactMessageType.ResponseUnsubscribe, this.id];
415288
}
416289

417-
public encodeCompact(codec: JsonValueCodec): void {
418-
codec.encoder.writeArr(this.toCompact());
419-
}
420-
421290
public encodeBinary(codec: JsonValueCodec): void {
422291
codec.encoder.writer.u32(0b11100000_00000001_00000000_00000000 | this.id);
423292
}

src/common/messages/types.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,5 @@ export interface Message<P = unknown> {
2929
value?: undefined | unknown;
3030
validate(): void;
3131
toCompact(): P;
32-
encodeCompact(codec: JsonValueCodec): void;
3332
encodeBinary(codec: JsonValueCodec): void;
3433
}

0 commit comments

Comments
 (0)