When compiling with TypeScript with module set to "node16" and
moduleResolution to "node16", the following error would be thrown:
> node_modules/engine.io-parser/build/cjs/index.d.ts:6:54 - error TS2304: Cannot find name 'TransformStream'.
> 6 export declare function createPacketEncoderStream(): TransformStream<Packet, any>;
> ~~~~~~~~~~~~~~~
> node_modules/engine.io-parser/build/cjs/index.d.ts:7:96 - error TS2304: Cannot find name 'TransformStream'.
> 7 export declare function createPacketDecoderStream(maxPayload: number, binaryType: BinaryType): TransformStream<Uint8Array, any>;
> ~~~~~~~~~~~~~~~
> Found 2 errors in the same file, starting at: node_modules/engine.io-parser/build/cjs/index.d.ts:6
This is because the TransformStream object is not exposed in the global
scope in the `@types/node` package, even though it is since Node.js
`v18.0.0`.
Reference: https://nodejs.org/api/webstreams.html#class-transformstream
Note: we only import the TransformStream type (not value) because it
isn't defined on older Node.js versions.
Related:
- https://github.com/socketio/engine.io-parser/issues/136
- https://github.com/socketio/socket.io-client/issues/1606
We could also split the declaration of RawData with the "browser"
field:
```
// for Node.js
export type RawData = string | Buffer | ArrayBuffer | ArrayBufferView; // no Blob
// for the browser
export type RawData = string | ArrayBuffer | ArrayBufferView | Blob; // no Buffer
```
But it does not seem supported by the TypeScript compiler, so we'll
revert to just using "any" for now.
Related: https://github.com/socketio/engine.io-parser/issues/128
The parser now returns the TypedArray object instead of the underlying
array buffer, so its offset and length are now taken in account (which
is the behavior of the classic WebSocket implementation).
Notes:
- this was already the case for the Node.js implementation
- in v3, the TypedArray object was always converted to an array buffer
because a byte was added at the beginning ("message" type)
- we could also have used "data.slice().buffer", but it would have
resulted in the copy of the buffer
Related:
- https://github.com/socketio/engine.io-parser/issues/122
- https://github.com/socketio/engine.io-client/issues/677
By default, terser (the mangler used by webpack) will replace the '\x1e'
by an unreadable character in the optimized output.
One solution would be to use the 'ascii_only' option:
```
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
output: {
ascii_only: true
}
}
})
]
}
};
```
But it would require anyone who tries to bundle the engine.io client to
use this plugin, so we'll rather use String.fromCharCode().
Note: String.fromCharCode(30) === '\u001e' === '\x1e'
See https://github.com/socketio/engine.io-protocol for the list of
changes.
Note: The 'base64-arraybuffer' dependency must now be explicitly
included by the client (not needed by the server).
Only packets of 'message' type can contain binary data, so it makes sense to remove the prefix in
order to avoid the concatenation of the packet type.
Breaking change: the packet containing binary data will now be sent without any transformation
Protocol v3: { type: 'message', data: <Buffer 01 02 03> } => <Buffer 04 01 02 03>
Protocol v4: { type: 'message', data: <Buffer 01 02 03> } => <Buffer 01 02 03>
That will allow clients receiving the xhr payload with
responseType = 'arraybuffer' to properly decode the message, which is
not sent as binary by the backend anymore since 292c00c (#85).
Since base64-arraybuffer version 0.1.5 introduced a change that fails
at require time in a browser without ArrayBuffer support, the require
must be guarded.
We always need to send binary when encoding payloads when sending from
server to client, because the polling transport has to know the response
type ahead of time.