Skip to content

Commit

Permalink
refactor: add additional types
Browse files Browse the repository at this point in the history
  • Loading branch information
darrachequesne committed Jan 17, 2022
1 parent 25a4b2b commit ad5bd7d
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 37 deletions.
22 changes: 21 additions & 1 deletion lib/commons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,26 @@ Object.keys(PACKET_TYPES).forEach(key => {
PACKET_TYPES_REVERSE[PACKET_TYPES[key]] = key;
});

const ERROR_PACKET = { type: "error", data: "parser error" };
const ERROR_PACKET: Packet = { type: "error", data: "parser error" };

export { PACKET_TYPES, PACKET_TYPES_REVERSE, ERROR_PACKET };

export type PacketType =
| "open"
| "close"
| "ping"
| "pong"
| "message"
| "upgrade"
| "noop"
| "error";

export type RawData = string | Buffer | ArrayBuffer | ArrayBufferView | Blob;

export interface Packet {
type: PacketType;
options?: { compress: boolean };
data?: RawData;
}

export type BinaryType = "nodebuffer" | "arraybuffer" | "blob";
13 changes: 11 additions & 2 deletions lib/decodePacket.browser.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
import { ERROR_PACKET, PACKET_TYPES_REVERSE } from "./commons.js";
import {
ERROR_PACKET,
PACKET_TYPES_REVERSE,
Packet,
BinaryType,
RawData
} from "./commons.js";
import { decode } from "@socket.io/base64-arraybuffer";

const withNativeArrayBuffer = typeof ArrayBuffer === "function";

const decodePacket = (encodedPacket, binaryType) => {
const decodePacket = (
encodedPacket: RawData,
binaryType?: BinaryType
): Packet => {
if (typeof encodedPacket !== "string") {
return {
type: "message",
Expand Down
17 changes: 13 additions & 4 deletions lib/decodePacket.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import { ERROR_PACKET, PACKET_TYPES_REVERSE } from "./commons.js";
import {
ERROR_PACKET,
PACKET_TYPES_REVERSE,
Packet,
BinaryType,
RawData
} from "./commons.js";

const decodePacket = (encodedPacket, binaryType?) => {
const decodePacket = (
encodedPacket: RawData,
binaryType?: BinaryType
): Packet => {
if (typeof encodedPacket !== "string") {
return {
type: "message",
Expand Down Expand Up @@ -28,7 +37,7 @@ const decodePacket = (encodedPacket, binaryType?) => {
};
};

const mapBinary = (data, binaryType) => {
const mapBinary = (data: RawData, binaryType?: BinaryType) => {
const isBuffer = Buffer.isBuffer(data);
switch (binaryType) {
case "arraybuffer":
Expand All @@ -39,7 +48,7 @@ const mapBinary = (data, binaryType) => {
}
};

const toArrayBuffer = buffer => {
const toArrayBuffer = (buffer: Buffer): ArrayBuffer => {
const arrayBuffer = new ArrayBuffer(buffer.length);
const view = new Uint8Array(arrayBuffer);
for (let i = 0; i < buffer.length; i++) {
Expand Down
13 changes: 10 additions & 3 deletions lib/encodePacket.browser.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { PACKET_TYPES } from "./commons.js";
import { PACKET_TYPES, Packet, RawData } from "./commons.js";

const withNativeBlob =
typeof Blob === "function" ||
Expand All @@ -13,7 +13,11 @@ const isView = obj => {
: obj && obj.buffer instanceof ArrayBuffer;
};

const encodePacket = ({ type, data }, supportsBinary, callback) => {
const encodePacket = (
{ type, data }: Packet,
supportsBinary: boolean,
callback: (encodedPacket: RawData) => void
) => {
if (withNativeBlob && data instanceof Blob) {
if (supportsBinary) {
return callback(data);
Expand All @@ -34,7 +38,10 @@ const encodePacket = ({ type, data }, supportsBinary, callback) => {
return callback(PACKET_TYPES[type] + (data || ""));
};

const encodeBlobAsBase64 = (data, callback) => {
const encodeBlobAsBase64 = (
data: Blob,
callback: (encodedPacket: RawData) => void
) => {
const fileReader = new FileReader();
fileReader.onload = function() {
const content = (fileReader.result as string).split(",")[1];
Expand Down
10 changes: 7 additions & 3 deletions lib/encodePacket.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { PACKET_TYPES } from "./commons.js";
import { PACKET_TYPES, Packet, RawData } from "./commons.js";

const encodePacket = ({ type, data }, supportsBinary, callback) => {
const encodePacket = (
{ type, data }: Packet,
supportsBinary: boolean,
callback: (encodedPacket: RawData) => void
) => {
if (data instanceof ArrayBuffer || ArrayBuffer.isView(data)) {
const buffer = toBuffer(data);
return callback(encodeBuffer(buffer, supportsBinary));
Expand All @@ -20,7 +24,7 @@ const toBuffer = data => {
};

// only 'message' packets can contain binary, so the type prefix is not needed
const encodeBuffer = (data, supportsBinary) => {
const encodeBuffer = (data: Buffer, supportsBinary: boolean): RawData => {
return supportsBinary ? data : "b" + data.toString("base64");
};

Expand Down
22 changes: 19 additions & 3 deletions lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import encodePacket from "./encodePacket.js";
import decodePacket from "./decodePacket.js";
import { Packet, PacketType, RawData, BinaryType } from "./commons";

const SEPARATOR = String.fromCharCode(30); // see https://en.wikipedia.org/wiki/Delimiter#ASCII_delimited_text

const encodePayload = (packets, callback) => {
const encodePayload = (
packets: Packet[],
callback: (encodedPayload: string) => void
) => {
// 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);
Expand All @@ -20,7 +24,10 @@ const encodePayload = (packets, callback) => {
});
};

const decodePayload = (encodedPayload, binaryType?) => {
const decodePayload = (
encodedPayload: string,
binaryType?: BinaryType
): Packet[] => {
const encodedPackets = encodedPayload.split(SEPARATOR);
const packets = [];
for (let i = 0; i < encodedPackets.length; i++) {
Expand All @@ -34,4 +41,13 @@ const decodePayload = (encodedPayload, binaryType?) => {
};

export const protocol = 4;
export { encodePacket, encodePayload, decodePacket, decodePayload };
export {
encodePacket,
encodePayload,
decodePacket,
decodePayload,
Packet,
PacketType,
RawData,
BinaryType
};
18 changes: 12 additions & 6 deletions test/browser.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { decodePacket, decodePayload, encodePacket, encodePayload } from "..";
import {
decodePacket,
decodePayload,
encodePacket,
encodePayload,
Packet
} from "..";
import * as expect from "expect.js";
import { areArraysEqual, createArrayBuffer } from "./util";

Expand All @@ -8,7 +14,7 @@ describe("engine.io-parser (browser only)", () => {
describe("single packet", () => {
if (withNativeArrayBuffer) {
it("should encode/decode an ArrayBuffer", done => {
const packet = {
const packet: Packet = {
type: "message",
data: createArrayBuffer([1, 2, 3, 4])
};
Expand All @@ -23,7 +29,7 @@ describe("engine.io-parser (browser only)", () => {
});

it("should encode/decode an ArrayBuffer as base64", done => {
const packet = {
const packet: Packet = {
type: "message",
data: createArrayBuffer([1, 2, 3, 4])
};
Expand All @@ -49,7 +55,7 @@ describe("engine.io-parser (browser only)", () => {

if (typeof Blob === "function") {
it("should encode/decode a Blob", done => {
const packet = {
const packet: Packet = {
type: "message",
data: new Blob(["1234", createArrayBuffer([1, 2, 3, 4])])
};
Expand All @@ -63,7 +69,7 @@ describe("engine.io-parser (browser only)", () => {
});

it("should encode/decode a Blob as base64", done => {
const packet = {
const packet: Packet = {
type: "message",
data: new Blob(["1234", createArrayBuffer([1, 2, 3, 4])])
};
Expand All @@ -81,7 +87,7 @@ describe("engine.io-parser (browser only)", () => {
describe("payload", () => {
if (withNativeArrayBuffer) {
it("should encode/decode a string + ArrayBuffer payload", done => {
const packets = [
const packets: Packet[] = [
{ type: "message", data: "test" },
{ type: "message", data: createArrayBuffer([1, 2, 3, 4]) }
];
Expand Down
18 changes: 12 additions & 6 deletions test/index.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,30 @@
import { decodePacket, decodePayload, encodePacket, encodePayload } from "..";
import {
decodePacket,
decodePayload,
encodePacket,
encodePayload,
Packet
} from "..";
import * as expect from "expect.js";
import "./node";

describe("engine.io-parser", () => {
describe("single packet", () => {
it("should encode/decode a string", done => {
const packet = { type: "message", data: "test" };
encodePacket(packet, {}, encodedPacket => {
const packet: Packet = { type: "message", data: "test" };
encodePacket(packet, true, encodedPacket => {
expect(encodedPacket).to.eql("4test");
expect(decodePacket(encodedPacket)).to.eql(packet);
done();
});
});

it("should fail to decode a malformed packet", () => {
expect(decodePacket("", {})).to.eql({
expect(decodePacket("")).to.eql({
type: "error",
data: "parser error"
});
expect(decodePacket("a123", {})).to.eql({
expect(decodePacket("a123")).to.eql({
type: "error",
data: "parser error"
});
Expand All @@ -27,7 +33,7 @@ describe("engine.io-parser", () => {

describe("payload", () => {
it("should encode/decode all packet types", done => {
const packets = [
const packets: Packet[] = [
{ type: "open" },
{ type: "close" },
{ type: "ping", data: "probe" },
Expand Down
30 changes: 21 additions & 9 deletions test/node.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,41 @@
import { decodePacket, decodePayload, encodePacket, encodePayload } from "..";
import {
decodePacket,
decodePayload,
encodePacket,
encodePayload,
Packet
} from "..";
import * as expect from "expect.js";
import { areArraysEqual } from "./util";

describe("engine.io-parser (node.js only)", () => {
describe("single packet", () => {
it("should encode/decode a Buffer", done => {
const packet = { type: "message", data: Buffer.from([1, 2, 3, 4]) };
const packet: Packet = {
type: "message",
data: Buffer.from([1, 2, 3, 4])
};
encodePacket(packet, true, encodedPacket => {
expect(encodedPacket).to.eql(packet.data); // noop
expect(decodePacket(encodedPacket, {})).to.eql(packet);
expect(decodePacket(encodedPacket)).to.eql(packet);
done();
});
});

it("should encode/decode a Buffer as base64", done => {
const packet = { type: "message", data: Buffer.from([1, 2, 3, 4]) };
const packet: Packet = {
type: "message",
data: Buffer.from([1, 2, 3, 4])
};
encodePacket(packet, false, encodedPacket => {
expect(encodedPacket).to.eql("bAQIDBA==");
expect(decodePacket(encodedPacket, "buffer")).to.eql(packet);
expect(decodePacket(encodedPacket, "nodebuffer")).to.eql(packet);
done();
});
});

it("should encode/decode an ArrayBuffer", done => {
const packet = {
const packet: Packet = {
type: "message",
data: Int8Array.from([1, 2, 3, 4]).buffer
};
Expand All @@ -38,7 +50,7 @@ describe("engine.io-parser (node.js only)", () => {
});

it("should encode/decode an ArrayBuffer as base64", done => {
const packet = {
const packet: Packet = {
type: "message",
data: Int8Array.from([1, 2, 3, 4]).buffer
};
Expand Down Expand Up @@ -83,13 +95,13 @@ describe("engine.io-parser (node.js only)", () => {

describe("payload", () => {
it("should encode/decode a string + Buffer payload", done => {
const packets = [
const packets: Packet[] = [
{ type: "message", data: "test" },
{ type: "message", data: Buffer.from([1, 2, 3, 4]) }
];
encodePayload(packets, payload => {
expect(payload).to.eql("4test\x1ebAQIDBA==");
expect(decodePayload(payload, "buffer")).to.eql(packets);
expect(decodePayload(payload, "nodebuffer")).to.eql(packets);
done();
});
});
Expand Down

0 comments on commit ad5bd7d

Please sign in to comment.