mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-09 16:13:31 +01:00
feat: zstd streaming support (#10758)
* feat(ws): zstd streaming support * chore: naming of the mode * fix: remove `@ts-expect-error` --------- Co-authored-by: Almeida <github@almeidx.dev>
This commit is contained in:
@@ -20,6 +20,7 @@ export enum Encoding {
|
||||
export enum CompressionMethod {
|
||||
ZlibNative,
|
||||
ZlibSync,
|
||||
ZstdNative,
|
||||
}
|
||||
|
||||
export const DefaultDeviceProperty = `@discordjs/ws [VI]{{inject}}[/VI]` as `@discordjs/ws ${string}`;
|
||||
@@ -29,6 +30,7 @@ const getDefaultSessionStore = lazy(() => new Collection<number, SessionInfo | n
|
||||
export const CompressionParameterMap = {
|
||||
[CompressionMethod.ZlibNative]: 'zlib-stream',
|
||||
[CompressionMethod.ZlibSync]: 'zlib-stream',
|
||||
[CompressionMethod.ZstdNative]: 'zstd-stream',
|
||||
} as const satisfies Record<CompressionMethod, string>;
|
||||
|
||||
/**
|
||||
|
||||
@@ -217,7 +217,7 @@ export class WebSocketShard extends AsyncEventEmitter<WebSocketShardEventsMap> {
|
||||
|
||||
this.nativeInflate = inflate;
|
||||
} else {
|
||||
console.warn('WebSocketShard: Compression is set to native but node:zlib is not available.');
|
||||
console.warn('WebSocketShard: Compression is set to native zlib but node:zlib is not available.');
|
||||
params.delete('compress');
|
||||
}
|
||||
|
||||
@@ -238,6 +238,34 @@ export class WebSocketShard extends AsyncEventEmitter<WebSocketShardEventsMap> {
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CompressionMethod.ZstdNative: {
|
||||
const zlib = await getNativeZlib();
|
||||
if (zlib && 'createZstdDecompress' in zlib) {
|
||||
this.inflateBuffer = [];
|
||||
|
||||
const inflate = zlib.createZstdDecompress({
|
||||
chunkSize: 65_535,
|
||||
}) as nativeZlib.Inflate;
|
||||
|
||||
inflate.on('data', (chunk) => {
|
||||
this.inflateBuffer.push(chunk);
|
||||
});
|
||||
|
||||
inflate.on('error', (error) => {
|
||||
this.emit(WebSocketShardEvents.Error, error);
|
||||
});
|
||||
|
||||
this.nativeInflate = inflate;
|
||||
} else {
|
||||
console.warn(
|
||||
'WebSocketShard: Compression is set to native zstd but node:zlib is not available or your node version does not support zstd decompression.',
|
||||
);
|
||||
params.delete('compress');
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -628,12 +656,14 @@ export class WebSocketShard extends AsyncEventEmitter<WebSocketShardEventsMap> {
|
||||
|
||||
// Deal with transport compression
|
||||
if (this.transportCompressionEnabled) {
|
||||
// Each WS message received is a full gateway message for zstd streaming, but for zlib it's chunked
|
||||
const flush =
|
||||
decompressable.length >= 4 &&
|
||||
decompressable.at(-4) === 0x00 &&
|
||||
decompressable.at(-3) === 0x00 &&
|
||||
decompressable.at(-2) === 0xff &&
|
||||
decompressable.at(-1) === 0xff;
|
||||
this.strategy.options.compression === CompressionMethod.ZstdNative ||
|
||||
(decompressable.length >= 4 &&
|
||||
decompressable.at(-4) === 0x00 &&
|
||||
decompressable.at(-3) === 0x00 &&
|
||||
decompressable.at(-2) === 0xff &&
|
||||
decompressable.at(-1) === 0xff);
|
||||
|
||||
if (this.nativeInflate) {
|
||||
const doneWriting = new Promise<void>((resolve) => {
|
||||
|
||||
Reference in New Issue
Block a user