| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 | "use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.decodePayload = exports.decodePacket = exports.encodePayload = exports.encodePacket = exports.protocol = exports.createPacketDecoderStream = exports.createPacketEncoderStream = void 0;const encodePacket_js_1 = require("./encodePacket.js");Object.defineProperty(exports, "encodePacket", { enumerable: true, get: function () { return encodePacket_js_1.encodePacket; } });const decodePacket_js_1 = require("./decodePacket.js");Object.defineProperty(exports, "decodePacket", { enumerable: true, get: function () { return decodePacket_js_1.decodePacket; } });const commons_js_1 = require("./commons.js");const SEPARATOR = String.fromCharCode(30); // see https://en.wikipedia.org/wiki/Delimiter#ASCII_delimited_textconst encodePayload = (packets, callback) => {    // some packets may be added to the array while encoding, so the initial length must be saved    const length = packets.length;    const encodedPackets = new Array(length);    let count = 0;    packets.forEach((packet, i) => {        // force base64 encoding for binary packets        (0, encodePacket_js_1.encodePacket)(packet, false, (encodedPacket) => {            encodedPackets[i] = encodedPacket;            if (++count === length) {                callback(encodedPackets.join(SEPARATOR));            }        });    });};exports.encodePayload = encodePayload;const decodePayload = (encodedPayload, binaryType) => {    const encodedPackets = encodedPayload.split(SEPARATOR);    const packets = [];    for (let i = 0; i < encodedPackets.length; i++) {        const decodedPacket = (0, decodePacket_js_1.decodePacket)(encodedPackets[i], binaryType);        packets.push(decodedPacket);        if (decodedPacket.type === "error") {            break;        }    }    return packets;};exports.decodePayload = decodePayload;function createPacketEncoderStream() {    // @ts-expect-error    return new TransformStream({        transform(packet, controller) {            (0, encodePacket_js_1.encodePacketToBinary)(packet, (encodedPacket) => {                const payloadLength = encodedPacket.length;                let header;                // inspired by the WebSocket format: https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers#decoding_payload_length                if (payloadLength < 126) {                    header = new Uint8Array(1);                    new DataView(header.buffer).setUint8(0, payloadLength);                }                else if (payloadLength < 65536) {                    header = new Uint8Array(3);                    const view = new DataView(header.buffer);                    view.setUint8(0, 126);                    view.setUint16(1, payloadLength);                }                else {                    header = new Uint8Array(9);                    const view = new DataView(header.buffer);                    view.setUint8(0, 127);                    view.setBigUint64(1, BigInt(payloadLength));                }                // first bit indicates whether the payload is plain text (0) or binary (1)                if (packet.data && typeof packet.data !== "string") {                    header[0] |= 0x80;                }                controller.enqueue(header);                controller.enqueue(encodedPacket);            });        },    });}exports.createPacketEncoderStream = createPacketEncoderStream;let TEXT_DECODER;function totalLength(chunks) {    return chunks.reduce((acc, chunk) => acc + chunk.length, 0);}function concatChunks(chunks, size) {    if (chunks[0].length === size) {        return chunks.shift();    }    const buffer = new Uint8Array(size);    let j = 0;    for (let i = 0; i < size; i++) {        buffer[i] = chunks[0][j++];        if (j === chunks[0].length) {            chunks.shift();            j = 0;        }    }    if (chunks.length && j < chunks[0].length) {        chunks[0] = chunks[0].slice(j);    }    return buffer;}function createPacketDecoderStream(maxPayload, binaryType) {    if (!TEXT_DECODER) {        TEXT_DECODER = new TextDecoder();    }    const chunks = [];    let state = 0 /* READ_HEADER */;    let expectedLength = -1;    let isBinary = false;    // @ts-expect-error    return new TransformStream({        transform(chunk, controller) {            chunks.push(chunk);            while (true) {                if (state === 0 /* READ_HEADER */) {                    if (totalLength(chunks) < 1) {                        break;                    }                    const header = concatChunks(chunks, 1);                    isBinary = (header[0] & 0x80) === 0x80;                    expectedLength = header[0] & 0x7f;                    if (expectedLength < 126) {                        state = 3 /* READ_PAYLOAD */;                    }                    else if (expectedLength === 126) {                        state = 1 /* READ_EXTENDED_LENGTH_16 */;                    }                    else {                        state = 2 /* READ_EXTENDED_LENGTH_64 */;                    }                }                else if (state === 1 /* READ_EXTENDED_LENGTH_16 */) {                    if (totalLength(chunks) < 2) {                        break;                    }                    const headerArray = concatChunks(chunks, 2);                    expectedLength = new DataView(headerArray.buffer, headerArray.byteOffset, headerArray.length).getUint16(0);                    state = 3 /* READ_PAYLOAD */;                }                else if (state === 2 /* READ_EXTENDED_LENGTH_64 */) {                    if (totalLength(chunks) < 8) {                        break;                    }                    const headerArray = concatChunks(chunks, 8);                    const view = new DataView(headerArray.buffer, headerArray.byteOffset, headerArray.length);                    const n = view.getUint32(0);                    if (n > Math.pow(2, 53 - 32) - 1) {                        // the maximum safe integer in JavaScript is 2^53 - 1                        controller.enqueue(commons_js_1.ERROR_PACKET);                        break;                    }                    expectedLength = n * Math.pow(2, 32) + view.getUint32(4);                    state = 3 /* READ_PAYLOAD */;                }                else {                    if (totalLength(chunks) < expectedLength) {                        break;                    }                    const data = concatChunks(chunks, expectedLength);                    controller.enqueue((0, decodePacket_js_1.decodePacket)(isBinary ? data : TEXT_DECODER.decode(data), binaryType));                    state = 0 /* READ_HEADER */;                }                if (expectedLength === 0 || expectedLength > maxPayload) {                    controller.enqueue(commons_js_1.ERROR_PACKET);                    break;                }            }        },    });}exports.createPacketDecoderStream = createPacketDecoderStream;exports.protocol = 4;
 |