@jsonjoy.com/reactive-rpc
Version:
Reactive-RPC is a library for building reactive APIs over WebSocket, HTTP, and other RPCs.
260 lines • 10.8 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.CompactRpcMessageCodec = void 0;
const tslib_1 = require("tslib");
const constants_1 = require("../constants");
const RpcError_1 = require("../../rpc/caller/error/RpcError");
const msg = tslib_1.__importStar(require("../../messages"));
const constants_2 = require("./constants");
const Value_1 = require("../../messages/Value");
const typed_1 = require("../../rpc/caller/error/typed");
const fromJson = (arr) => {
if (!(arr instanceof Array))
throw RpcError_1.RpcError.badRequest();
const type = arr[0];
switch (type) {
case constants_2.CompactMessageType.RequestComplete: {
const data = arr[3];
const value = data === undefined ? data : new Value_1.RpcValue(data, undefined);
return new msg.RequestCompleteMessage(arr[1], arr[2], value);
}
case constants_2.CompactMessageType.RequestData: {
const data = arr[3];
const value = data === undefined ? data : new Value_1.RpcValue(data, undefined);
return new msg.RequestDataMessage(arr[1], arr[2], value);
}
case constants_2.CompactMessageType.RequestError: {
return new msg.RequestErrorMessage(arr[1], arr[2], new Value_1.RpcValue(arr[3], undefined));
}
case constants_2.CompactMessageType.RequestUnsubscribe: {
return new msg.RequestUnsubscribeMessage(arr[1]);
}
case constants_2.CompactMessageType.ResponseComplete: {
const data = arr[2];
const value = data === undefined ? data : new Value_1.RpcValue(data, undefined);
return new msg.ResponseCompleteMessage(arr[1], value);
}
case constants_2.CompactMessageType.ResponseData: {
return new msg.ResponseDataMessage(arr[1], new Value_1.RpcValue(arr[2], undefined));
}
case constants_2.CompactMessageType.ResponseError: {
return new msg.ResponseErrorMessage(arr[1], new Value_1.RpcValue(arr[2], undefined));
}
case constants_2.CompactMessageType.ResponseUnsubscribe: {
return new msg.ResponseUnsubscribeMessage(arr[1]);
}
case constants_2.CompactMessageType.Notification: {
return new msg.NotificationMessage(arr[1], new Value_1.RpcValue(arr[2], undefined));
}
}
throw typed_1.TypedRpcError.value(RpcError_1.RpcError.validation('Unknown message type'));
};
const encodeCompactWithNameAndPayload = (codec, type, msg) => {
const encoder = codec.encoder;
if (typeof encoder.writeArrHdr === 'function') {
const binaryEncoder = encoder;
const value = msg.value;
const hasValue = value !== undefined;
binaryEncoder.writeArrHdr(hasValue ? 4 : 3);
encoder.writeUInteger(type);
encoder.writeUInteger(msg.id);
encoder.writeAsciiStr(msg.method);
if (hasValue) {
if (value.type)
value.type.encoder(codec.format)(value.data, encoder);
else
encoder.writeAny(value.data);
}
}
else if (typeof encoder.writeStartArr === 'function' &&
typeof encoder.writeArrSeparator === 'function') {
const jsonEncoder = encoder;
const value = msg.value;
jsonEncoder.writeStartArr();
jsonEncoder.writeNumber(type);
jsonEncoder.writeArrSeparator();
jsonEncoder.writeNumber(msg.id);
jsonEncoder.writeArrSeparator();
jsonEncoder.writeAsciiStr(msg.method);
const hasValue = value !== undefined;
if (hasValue) {
jsonEncoder.writeArrSeparator();
if (value.type)
value.type.encoder(codec.format)(value.data, encoder);
else
jsonEncoder.writeAny(value.data);
}
jsonEncoder.writeEndArr();
}
else
encoder.writeArr(msg.toCompact());
};
const encodeCompactWithPayload = (codec, type, msg) => {
const encoder = codec.encoder;
if (typeof encoder.writeArrHdr === 'function') {
const binaryEncoder = encoder;
const value = msg.value;
const hasValue = value !== undefined;
binaryEncoder.writeArrHdr(hasValue ? 3 : 2);
encoder.writeUInteger(type);
encoder.writeUInteger(msg.id);
if (hasValue) {
if (value.type) {
value.type.encoder(codec.format)(value.data, encoder);
}
else
encoder.writeAny(value.data);
}
}
else if (typeof encoder.writeStartArr === 'function' &&
typeof encoder.writeArrSeparator === 'function') {
const jsonEncoder = encoder;
const value = msg.value;
jsonEncoder.writeStartArr();
jsonEncoder.writeNumber(type);
jsonEncoder.writeArrSeparator();
jsonEncoder.writeNumber(msg.id);
const hasValue = value !== undefined;
if (hasValue) {
jsonEncoder.writeArrSeparator();
if (value.type)
value.type.encoder(codec.format)(value.data, jsonEncoder);
else
encoder.writeAny(value.data);
}
jsonEncoder.writeEndArr();
}
else
encoder.writeArr(msg.toCompact());
};
class CompactRpcMessageCodec {
constructor() {
this.id = 'rx.compact';
this.format = constants_1.RpcMessageFormat.Compact;
}
encodeMessage(codec, message) {
if (message instanceof msg.NotificationMessage) {
const encoder = codec.encoder;
if (typeof encoder.writeArrHdr === 'function') {
const binaryEncoder = encoder;
const value = message.value;
const hasValue = value !== undefined;
binaryEncoder.writeArrHdr(hasValue ? 3 : 2);
encoder.writeUInteger(constants_2.CompactMessageType.Notification);
encoder.writeAsciiStr(message.method);
if (hasValue) {
if (value.type)
value.type.encoder(codec.format)(value.data, encoder);
else
encoder.writeAny(value.data);
}
}
else if (typeof encoder.writeStartArr === 'function' &&
typeof encoder.writeArrSeparator === 'function') {
const jsonEncoder = encoder;
const value = message.value;
jsonEncoder.writeStartArr();
jsonEncoder.writeNumber(constants_2.CompactMessageType.Notification);
jsonEncoder.writeArrSeparator();
jsonEncoder.writeAsciiStr(message.method);
const hasValue = value !== undefined;
if (hasValue) {
jsonEncoder.writeArrSeparator();
if (value.type)
value.type.encoder(codec.format)(value.data, jsonEncoder);
else
encoder.writeAny(value.data);
}
jsonEncoder.writeEndArr();
}
else
encoder.writeArr(message.toCompact());
}
else if (message instanceof msg.RequestDataMessage) {
encodeCompactWithNameAndPayload(codec, constants_2.CompactMessageType.RequestData, message);
}
else if (message instanceof msg.RequestCompleteMessage) {
encodeCompactWithNameAndPayload(codec, constants_2.CompactMessageType.RequestComplete, message);
}
else if (message instanceof msg.RequestErrorMessage) {
encodeCompactWithNameAndPayload(codec, constants_2.CompactMessageType.RequestError, message);
}
else if (message instanceof msg.RequestUnsubscribeMessage) {
codec.encoder.writeArr(message.toCompact());
}
else if (message instanceof msg.ResponseCompleteMessage) {
encodeCompactWithPayload(codec, constants_2.CompactMessageType.ResponseComplete, message);
}
else if (message instanceof msg.ResponseDataMessage) {
encodeCompactWithPayload(codec, constants_2.CompactMessageType.ResponseData, message);
}
else if (message instanceof msg.ResponseErrorMessage) {
encodeCompactWithPayload(codec, constants_2.CompactMessageType.ResponseError, message);
}
else if (message instanceof msg.ResponseUnsubscribeMessage) {
codec.encoder.writeArr(message.toCompact());
}
else {
codec.encoder.writeArr(message.toCompact());
}
}
encodeBatch(jsonCodec, batch) {
const encoder = jsonCodec.encoder;
if (typeof encoder.writeArrHdr === 'function') {
const binaryEncoder = encoder;
const length = batch.length;
binaryEncoder.writeArrHdr(length);
for (let i = 0; i < length; i++)
this.encodeMessage(jsonCodec, batch[i]);
}
else if (typeof encoder.writeStartArr === 'function' &&
typeof encoder.writeArrSeparator === 'function') {
const jsonEncoder = encoder;
const length = batch.length;
const last = length - 1;
jsonEncoder.writeStartArr();
for (let i = 0; i < last; i++) {
this.encodeMessage(jsonCodec, batch[i]);
jsonEncoder.writeArrSeparator();
}
if (length > 0)
this.encodeMessage(jsonCodec, batch[last]);
jsonEncoder.writeEndArr();
}
else {
const jsonMessages = [];
const length = batch.length;
for (let i = 0; i < length; i++)
jsonMessages.push(batch[i].toCompact());
const encoder = jsonCodec.encoder;
encoder.writeArr(jsonMessages);
}
}
encode(jsonCodec, batch) {
const encoder = jsonCodec.encoder;
const writer = encoder.writer;
writer.reset();
this.encodeBatch(jsonCodec, batch);
return writer.flush();
}
decodeBatch(jsonCodec, uint8) {
const decoder = jsonCodec.decoder;
const value = decoder.read(uint8);
if (!(value instanceof Array))
throw RpcError_1.RpcError.badRequest();
if (typeof value[0] === 'number')
return [fromJson(value)];
const result = [];
const length = value.length;
for (let i = 0; i < length; i++) {
const item = value[i];
result.push(fromJson(item));
}
return result;
}
fromJson(compact) {
return fromJson(compact);
}
}
exports.CompactRpcMessageCodec = CompactRpcMessageCodec;
//# sourceMappingURL=CompactRpcMessageCodec.js.map
;