@eulerstream/euler-websocket-sdk
Version:
Browser & Node.JS cross-compatible module for the Euler Stream WebSocket service.
106 lines • 4.84 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.createBaseWebcastPushFrame = exports.deserializeWebSocketMessage = exports.deserializeMessage = exports.NoSchemaFoundError = void 0;
const schemas_1 = require("./schemas");
const fflate_1 = require("fflate");
class NoSchemaFoundError extends Error {
constructor(message) {
super(message);
this.name = "NoSchemaFoundError";
}
}
exports.NoSchemaFoundError = NoSchemaFoundError;
/**
* Deserialize ProtoMessageFetchResult and all nested messages
*
* @param protoBinary Binary
* @param protoSchemaVersion Version to use when deserializing nested messages
*/
function deserializeProtoMessageFetchResult(protoBinary, protoSchemaVersion) {
// Always pull from Schema V2 for ProtoMessageFetchResult
const protoMessageFetchResult = schemas_1.WebcastSchemas[schemas_1.SchemaVersion.v2]
.ProtoMessageFetchResultDecoder
.decode(protoBinary);
const selectedSchema = schemas_1.WebcastSchemas[protoSchemaVersion];
for (const message of protoMessageFetchResult.messages || []) {
// Skip it if it's not in the schema
if (!selectedSchema[`${message.type}Decoder`]) {
continue;
}
// Deserialize the message
try {
const messageType = message.type;
const deserializedMessage = deserializeMessage(messageType, message.payload, protoSchemaVersion);
message.decodedData = { type: messageType, data: deserializedMessage };
}
catch (ex) {
console.info(`Failed to decode message type: ${message.type}`, ex);
}
}
return protoMessageFetchResult;
}
/**
* Deserialize any message
*
* @param protoName Name of the proto to deserialize
* @param protoBinary Binary for the deserialized proto
* @param protoVersion Version of the proto schema to use
*/
function deserializeMessage(protoName, protoBinary, protoVersion) {
// These have nested message binaries in them, so we have a custom decoder ^.^
if (protoName === "ProtoMessageFetchResult") {
return deserializeProtoMessageFetchResult(protoBinary, protoVersion);
}
// Get the decoder name
const decoderName = `${protoName}Decoder`;
const decoderFn = schemas_1.WebcastSchemas[protoVersion][decoderName];
if (!decoderFn) {
throw new NoSchemaFoundError(`Invalid schema name: ${protoName}, not found in the Protobuf schema.`);
}
return decoderFn.decode(protoBinary);
}
exports.deserializeMessage = deserializeMessage;
/**
* Deserialize a WebSocket message into a DecodedWebcastPushFrame
*
* @param protoBinary Binary message received from the WebSocket
* @param protoSchemaVersion Version of the schema to use when deserializing nested messages
*/
function deserializeWebSocketMessage(protoBinary, protoSchemaVersion) {
// Websocket messages are in a container which contains additional data
// Message type 'msg' represents a normal ProtoMessageFetchResult
const rawWebcastWebSocketMessage = schemas_1.WebcastPushFrameDecoder.decode(protoBinary); // Always with v2
let protoMessageFetchResult = undefined;
if (rawWebcastWebSocketMessage.payloadEncoding === 'pb' && rawWebcastWebSocketMessage.payload) {
let binary = rawWebcastWebSocketMessage.payload;
// Decompress binary (if gzip compressed—which)
// It isn't in the WebSocket server to safe CPU but may be if users use this pkg to decompress manually for debugging
// https://www.rfc-editor.org/rfc/rfc1950.html
if (binary && binary.length > 2 && binary[0] === 0x1f && binary[1] === 0x8b && binary[2] === 0x08) {
rawWebcastWebSocketMessage.payload = (0, fflate_1.gunzipSync)(binary);
}
protoMessageFetchResult = deserializeMessage('ProtoMessageFetchResult', rawWebcastWebSocketMessage.payload, protoSchemaVersion);
}
const decodedContainer = rawWebcastWebSocketMessage;
decodedContainer.protoMessageFetchResult = protoMessageFetchResult;
return decodedContainer;
}
exports.deserializeWebSocketMessage = deserializeWebSocketMessage;
function createBaseWebcastPushFrame(overrides) {
// Basically, we need to set it to "0" so that it DOES NOT send the field(s)
const undefinedNum = '0';
overrides = Object.fromEntries(Object.entries(overrides).filter(([_, value]) => value !== undefined));
return schemas_1.WebcastPushFrameDecoder.encode({
seqId: undefinedNum,
logId: undefinedNum,
payloadEncoding: 'pb',
payloadType: 'msg',
payload: new Uint8Array(),
service: undefinedNum,
method: undefinedNum,
headers: {},
...overrides
});
}
exports.createBaseWebcastPushFrame = createBaseWebcastPushFrame;
//# sourceMappingURL=proto-utils.js.map
;