Repository: discordjs/discord.js
File: packages/ws/src/ws/WebSocketShard.ts (TypeScript)

Code before:
				return JSON.parse(data as string) as GatewayReceivePayload;
			} catch {
				// This is a non-JSON payload / (at the time of writing this comment) emitted by bun wrongly interpreting custom close codes https://github.com/oven-sh/bun/issues/3392
				return null;
			}
		}

		const decompressable = new Uint8Array(data as ArrayBuffer);

		// Deal with identify compress
		if (this.identifyCompressionEnabled) {
			// eslint-disable-next-line no-async-promise-executor
			return new Promise(async (resolve, reject) => {
				const zlib = (await getNativeZlib())!;
				// eslint-disable-next-line promise/prefer-await-to-callbacks
				zlib.inflate(decompressable, { chunkSize: 65_535 }, (err, result) => {
					if (err) {
						reject(err);
						return;
					}

					resolve(JSON.parse(this.textDecoder.decode(result)) as GatewayReceivePayload);
				});
			});
		}

		// 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 =
				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) => {
					// eslint-disable-next-line promise/prefer-await-to-callbacks
					this.nativeInflate!.write(decompressable, 'binary', (error) => {
						if (error) {
							this.emit(WebSocketShardEvents.Error, error);
						}

						resolve();
					});
				});

				if (!flush) {
					return null;

Review comment (suggestion):
I know this is a draft, but flagging now

This check isn't correct, because there's cases where we don't uphold the compression option passes (i.e. the logic in the constructor). I think generally the other code relies on the presence of the Inflate objects specific to that method.

Code after:
		}

		const decompressable = new Uint8Array(data as ArrayBuffer);

		// Deal with identify compress
		if (this.identifyCompressionEnabled) {
			// eslint-disable-next-line no-async-promise-executor
			return new Promise(async (resolve, reject) => {
				const zlib = (await getNativeZlib())!;
				// eslint-disable-next-line promise/prefer-await-to-callbacks
				zlib.inflate(decompressable, { chunkSize: 65_535 }, (err, result) => {
					if (err) {
						reject(err);
						return;
					}

					resolve(JSON.parse(this.textDecoder.decode(result)) as GatewayReceivePayload);
				});
			});
		}

		// 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 =
				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) => {
					// eslint-disable-next-line promise/prefer-await-to-callbacks
					this.nativeInflate!.write(decompressable, 'binary', (error) => {
						if (error) {
							this.emit(WebSocketShardEvents.Error, error);
						}

						resolve();
					});
				});

				if (!flush) {
					return null;
				}

				// This way we're ensuring the latest write has flushed and our buffer is ready
				await doneWriting;