feat: upgrade socket.io to v4

Signed-off-by: MiaoWoo <admin@yumc.pw>
This commit is contained in:
2022-11-21 23:18:39 +08:00
parent e563e1b507
commit df0d246136
45 changed files with 6585 additions and 1734 deletions

View File

@@ -1,4 +1,4 @@
import { isBinary } from "./is-binary"
import { isBinary } from "./is-binary.js"
/**
* Replaces every Buffer | ArrayBuffer | Blob | File in packet with a numbered placeholder.
@@ -33,7 +33,7 @@ function _deconstructPacket(data, buffers) {
} else if (typeof data === "object" && !(data instanceof Date)) {
const newData = {}
for (const key in data) {
if (data.hasOwnProperty(key)) {
if (Object.prototype.hasOwnProperty.call(data, key)) {
newData[key] = _deconstructPacket(data[key], buffers)
}
}
@@ -60,15 +60,23 @@ export function reconstructPacket(packet, buffers) {
function _reconstructPacket(data, buffers) {
if (!data) return data
if (data && data._placeholder) {
return buffers[data.num] // appropriate buffer (should be natural order anyway)
if (data && data._placeholder === true) {
const isIndexValid =
typeof data.num === "number" &&
data.num >= 0 &&
data.num < buffers.length
if (isIndexValid) {
return buffers[data.num] // appropriate buffer (should be natural order anyway)
} else {
throw new Error("illegal attachments")
}
} else if (Array.isArray(data)) {
for (let i = 0; i < data.length; i++) {
data[i] = _reconstructPacket(data[i], buffers)
}
} else if (typeof data === "object") {
for (const key in data) {
if (data.hasOwnProperty(key)) {
if (Object.prototype.hasOwnProperty.call(data, key)) {
data[key] = _reconstructPacket(data[key], buffers)
}
}

View File

@@ -1,8 +1,10 @@
import EventEmitter = require("events")
import { deconstructPacket, reconstructPacket } from "./binary"
import { isBinary, hasBinary } from "./is-binary"
import { Emitter } from "@socket.io/component-emitter"
import { deconstructPacket, reconstructPacket } from "./binary.js"
import { isBinary, hasBinary } from "./is-binary.js"
// import debugModule from "debug" // debug()
// const debug = require("debug")("socket.io-parser")
// const debug = debugModule("socket.io-parser") // debug()
const debug = require("../debug")("socket.io-client")
/**
* Protocol version.
@@ -35,6 +37,12 @@ export interface Packet {
*/
export class Encoder {
/**
* Encoder constructor
*
* @param {function} replacer - custom replacer to pass down to JSON.parse
*/
constructor(private replacer?: (this: any, key: string, value: any) => any) { }
/**
* Encode a packet as a single string if non-binary, or as a
* buffer sequence, depending on packet type.
@@ -42,7 +50,7 @@ export class Encoder {
* @param {Object} obj - packet object
*/
public encode(obj: Packet) {
console.trace("encoding packet", JSON.stringify(obj))
debug("encoding packet %j", obj)
if (obj.type === PacketType.EVENT || obj.type === PacketType.ACK) {
if (hasBinary(obj)) {
@@ -85,10 +93,10 @@ export class Encoder {
// json data
if (null != obj.data) {
str += JSON.stringify(obj.data)
str += JSON.stringify(obj.data, this.replacer)
}
console.trace("encoded", JSON.stringify(obj), "as", str)
debug("encoded %j as %s", obj, str)
return str
}
@@ -108,15 +116,24 @@ export class Encoder {
}
}
interface DecoderReservedEvents {
decoded: (packet: Packet) => void
}
/**
* A socket.io Decoder instance
*
* @return {Object} decoder
*/
export class Decoder extends EventEmitter {
export class Decoder extends Emitter<{}, {}, DecoderReservedEvents> {
private reconstructor: BinaryReconstructor
constructor() {
/**
* Decoder constructor
*
* @param {function} reviver - custom reviver to pass down to JSON.stringify
*/
constructor(private reviver?: (this: any, key: string, value: any) => any) {
super()
}
@@ -129,6 +146,9 @@ export class Decoder extends EventEmitter {
public add(obj: any) {
let packet
if (typeof obj === "string") {
if (this.reconstructor) {
throw new Error("got plaintext data when reconstructing a packet")
}
packet = this.decodeString(obj)
if (
packet.type === PacketType.BINARY_EVENT ||
@@ -139,11 +159,11 @@ export class Decoder extends EventEmitter {
// no attachments, labeled binary but no binary data to follow
if (packet.attachments === 0) {
super.emit("decoded", packet)
super.emitReserved("decoded", packet)
}
} else {
// non-binary full packet
super.emit("decoded", packet)
super.emitReserved("decoded", packet)
}
} else if (isBinary(obj) || obj.base64) {
// raw binary data
@@ -154,7 +174,7 @@ export class Decoder extends EventEmitter {
if (packet) {
// received final buffer
this.reconstructor = null
super.emit("decoded", packet)
super.emitReserved("decoded", packet)
}
}
} else {
@@ -223,7 +243,7 @@ export class Decoder extends EventEmitter {
// look up json data
if (str.charAt(++i)) {
const payload = tryParse(str.substr(i))
const payload = this.tryParse(str.substr(i))
if (Decoder.isPayloadValid(p.type, payload)) {
p.data = payload
} else {
@@ -231,10 +251,18 @@ export class Decoder extends EventEmitter {
}
}
console.trace("decoded", str, "as", p)
debug("decoded %s as %j", str, p)
return p
}
private tryParse(str) {
try {
return JSON.parse(str, this.reviver)
} catch (e) {
return false
}
}
private static isPayloadValid(type: PacketType, payload: any): boolean {
switch (type) {
case PacketType.CONNECT:
@@ -262,14 +290,6 @@ export class Decoder extends EventEmitter {
}
}
function tryParse(str) {
try {
return JSON.parse(str)
} catch (error: any) {
return false
}
}
/**
* A manager of a binary event's 'buffer sequence'. Should
* be constructed whenever a packet of type BINARY_EVENT is

View File

@@ -7,14 +7,14 @@ const isView = (obj: any) => {
}
const toString = Object.prototype.toString
const withNativeBlob = false
// typeof Blob === "function" ||
// (typeof Blob !== "undefined" &&
// toString.call(Blob) === "[object BlobConstructor]")
const withNativeFile = false
// typeof File === "function" ||
// (typeof File !== "undefined" &&
// toString.call(File) === "[object FileConstructor]")
const withNativeBlob =
typeof Blob === "function" ||
(typeof Blob !== "undefined" &&
toString.call(Blob) === "[object BlobConstructor]")
const withNativeFile =
typeof File === "function" ||
(typeof File !== "undefined" &&
toString.call(File) === "[object FileConstructor]")
/**
* Returns true if obj is a Buffer, an ArrayBuffer, a Blob or a File.
@@ -24,8 +24,9 @@ const withNativeFile = false
export function isBinary(obj: any) {
return (
(withNativeArrayBuffer && (obj instanceof ArrayBuffer || isView(obj)))
// || (withNativeBlob && obj instanceof Blob) || (withNativeFile && obj instanceof File)
(withNativeArrayBuffer && (obj instanceof ArrayBuffer || isView(obj))) ||
(withNativeBlob && obj instanceof Blob) ||
(withNativeFile && obj instanceof File)
)
}