UNPKG

@eulerstream/euler-websocket-sdk

Version:

Browser & Node.JS cross-compatible module for the Euler Stream WebSocket service.

106 lines 4.84 kB
"use strict"; 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