@discordjs/ws 1.1.1 → 1.1.2-dev.1717373416-94cc02a25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -1
- package/dist/defaultWorker.js +115 -46
- package/dist/defaultWorker.js.map +1 -1
- package/dist/defaultWorker.mjs +115 -46
- package/dist/defaultWorker.mjs.map +1 -1
- package/dist/index.d.mts +27 -6
- package/dist/index.d.ts +27 -6
- package/dist/index.js +116 -49
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +115 -49
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -50,7 +50,10 @@ const manager = new WebSocketManager({
|
|
|
50
50
|
intents: 0, // for no intents
|
|
51
51
|
rest,
|
|
52
52
|
// uncomment if you have zlib-sync installed and want to use compression
|
|
53
|
-
// compression: CompressionMethod.
|
|
53
|
+
// compression: CompressionMethod.ZlibSync,
|
|
54
|
+
|
|
55
|
+
// alternatively, we support compression using node's native `node:zlib` module:
|
|
56
|
+
// compression: CompressionMethod.ZlibNative,
|
|
54
57
|
});
|
|
55
58
|
|
|
56
59
|
manager.on(WebSocketShardEvents.Dispatch, (event) => {
|
package/dist/defaultWorker.js
CHANGED
|
@@ -141,7 +141,6 @@ var import_node_timers = require("timers");
|
|
|
141
141
|
var import_promises2 = require("timers/promises");
|
|
142
142
|
var import_node_url = require("url");
|
|
143
143
|
var import_node_util = require("util");
|
|
144
|
-
var import_node_zlib = require("zlib");
|
|
145
144
|
var import_collection6 = require("@discordjs/collection");
|
|
146
145
|
var import_util2 = require("@discordjs/util");
|
|
147
146
|
var import_async_queue2 = require("@sapphire/async-queue");
|
|
@@ -292,8 +291,17 @@ var SimpleIdentifyThrottler = class {
|
|
|
292
291
|
};
|
|
293
292
|
|
|
294
293
|
// src/utils/constants.ts
|
|
294
|
+
var CompressionMethod = /* @__PURE__ */ ((CompressionMethod2) => {
|
|
295
|
+
CompressionMethod2[CompressionMethod2["ZlibNative"] = 0] = "ZlibNative";
|
|
296
|
+
CompressionMethod2[CompressionMethod2["ZlibSync"] = 1] = "ZlibSync";
|
|
297
|
+
return CompressionMethod2;
|
|
298
|
+
})(CompressionMethod || {});
|
|
295
299
|
var DefaultDeviceProperty = `@discordjs/ws [VI]{{inject}}[/VI]`;
|
|
296
300
|
var getDefaultSessionStore = (0, import_util.lazy)(() => new import_collection5.Collection());
|
|
301
|
+
var CompressionParameterMap = {
|
|
302
|
+
[0 /* ZlibNative */]: "zlib-stream",
|
|
303
|
+
[1 /* ZlibSync */]: "zlib-stream"
|
|
304
|
+
};
|
|
297
305
|
var DefaultWebSocketManagerOptions = {
|
|
298
306
|
async buildIdentifyThrottler(manager) {
|
|
299
307
|
const info = await manager.fetchGatewayInformation();
|
|
@@ -312,6 +320,7 @@ var DefaultWebSocketManagerOptions = {
|
|
|
312
320
|
version: import_v10.APIVersion,
|
|
313
321
|
encoding: "json" /* JSON */,
|
|
314
322
|
compression: null,
|
|
323
|
+
useIdentifyCompression: false,
|
|
315
324
|
retrieveSessionInfo(shardId) {
|
|
316
325
|
const store = getDefaultSessionStore();
|
|
317
326
|
return store.get(shardId) ?? null;
|
|
@@ -343,6 +352,7 @@ __name(getInitialSendRateLimitState, "getInitialSendRateLimitState");
|
|
|
343
352
|
|
|
344
353
|
// src/ws/WebSocketShard.ts
|
|
345
354
|
var getZlibSync = (0, import_util2.lazy)(async () => import("zlib-sync").then((mod) => mod.default).catch(() => null));
|
|
355
|
+
var getNativeZlib = (0, import_util2.lazy)(async () => import("zlib").then((mod) => mod).catch(() => null));
|
|
346
356
|
var WebSocketShardEvents = /* @__PURE__ */ ((WebSocketShardEvents2) => {
|
|
347
357
|
WebSocketShardEvents2["Closed"] = "closed";
|
|
348
358
|
WebSocketShardEvents2["Debug"] = "debug";
|
|
@@ -365,8 +375,8 @@ var WebSocketShard = class extends import_async_event_emitter.AsyncEventEmitter
|
|
|
365
375
|
__name(this, "WebSocketShard");
|
|
366
376
|
}
|
|
367
377
|
connection = null;
|
|
368
|
-
|
|
369
|
-
|
|
378
|
+
nativeInflate = null;
|
|
379
|
+
zLibSyncInflate = null;
|
|
370
380
|
textDecoder = new import_node_util.TextDecoder();
|
|
371
381
|
replayedEvents = 0;
|
|
372
382
|
isAck = true;
|
|
@@ -383,6 +393,16 @@ var WebSocketShard = class extends import_async_event_emitter.AsyncEventEmitter
|
|
|
383
393
|
strategy;
|
|
384
394
|
id;
|
|
385
395
|
#status = 0 /* Idle */;
|
|
396
|
+
identifyCompressionEnabled = false;
|
|
397
|
+
/**
|
|
398
|
+
* @privateRemarks
|
|
399
|
+
*
|
|
400
|
+
* This is needed because `this.strategy.options.compression` is not an actual reflection of the compression method
|
|
401
|
+
* used, but rather the compression method that the user wants to use. This is because the libraries could just be missing.
|
|
402
|
+
*/
|
|
403
|
+
get transportCompressionEnabled() {
|
|
404
|
+
return this.strategy.options.compression !== null && (this.nativeInflate ?? this.zLibSyncInflate) !== null;
|
|
405
|
+
}
|
|
386
406
|
get status() {
|
|
387
407
|
return this.#status;
|
|
388
408
|
}
|
|
@@ -414,21 +434,53 @@ var WebSocketShard = class extends import_async_event_emitter.AsyncEventEmitter
|
|
|
414
434
|
if (this.#status !== 0 /* Idle */) {
|
|
415
435
|
throw new Error("Tried to connect a shard that wasn't idle");
|
|
416
436
|
}
|
|
417
|
-
const { version, encoding, compression } = this.strategy.options;
|
|
437
|
+
const { version, encoding, compression, useIdentifyCompression } = this.strategy.options;
|
|
438
|
+
this.identifyCompressionEnabled = useIdentifyCompression;
|
|
418
439
|
const params = new import_node_url.URLSearchParams({ v: version, encoding });
|
|
419
|
-
if (compression) {
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
440
|
+
if (compression !== null) {
|
|
441
|
+
if (useIdentifyCompression) {
|
|
442
|
+
console.warn("WebSocketShard: transport compression is enabled, disabling identify compression");
|
|
443
|
+
this.identifyCompressionEnabled = false;
|
|
444
|
+
}
|
|
445
|
+
params.append("compress", CompressionParameterMap[compression]);
|
|
446
|
+
switch (compression) {
|
|
447
|
+
case 0 /* ZlibNative */: {
|
|
448
|
+
const zlib = await getNativeZlib();
|
|
449
|
+
if (zlib) {
|
|
450
|
+
const inflate = zlib.createInflate({
|
|
451
|
+
chunkSize: 65535,
|
|
452
|
+
flush: zlib.constants.Z_SYNC_FLUSH
|
|
453
|
+
});
|
|
454
|
+
inflate.on("error", (error) => {
|
|
455
|
+
this.emit("error" /* Error */, { error });
|
|
456
|
+
});
|
|
457
|
+
this.nativeInflate = inflate;
|
|
458
|
+
} else {
|
|
459
|
+
console.warn("WebSocketShard: Compression is set to native but node:zlib is not available.");
|
|
460
|
+
params.delete("compress");
|
|
461
|
+
}
|
|
462
|
+
break;
|
|
463
|
+
}
|
|
464
|
+
case 1 /* ZlibSync */: {
|
|
465
|
+
const zlib = await getZlibSync();
|
|
466
|
+
if (zlib) {
|
|
467
|
+
this.zLibSyncInflate = new zlib.Inflate({
|
|
468
|
+
chunkSize: 65535,
|
|
469
|
+
to: "string"
|
|
470
|
+
});
|
|
471
|
+
} else {
|
|
472
|
+
console.warn("WebSocketShard: Compression is set to zlib-sync, but it is not installed.");
|
|
473
|
+
params.delete("compress");
|
|
474
|
+
}
|
|
475
|
+
break;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
if (this.identifyCompressionEnabled) {
|
|
480
|
+
const zlib = await getNativeZlib();
|
|
481
|
+
if (!zlib) {
|
|
482
|
+
console.warn("WebSocketShard: Identify compression is enabled, but node:zlib is not available.");
|
|
483
|
+
this.identifyCompressionEnabled = false;
|
|
432
484
|
}
|
|
433
485
|
}
|
|
434
486
|
const session = await this.strategy.retrieveSessionInfo(this.id);
|
|
@@ -622,24 +674,25 @@ var WebSocketShard = class extends import_async_event_emitter.AsyncEventEmitter
|
|
|
622
674
|
`shard id: ${this.id.toString()}`,
|
|
623
675
|
`shard count: ${this.strategy.options.shardCount}`,
|
|
624
676
|
`intents: ${this.strategy.options.intents}`,
|
|
625
|
-
`compression: ${this.
|
|
677
|
+
`compression: ${this.transportCompressionEnabled ? CompressionParameterMap[this.strategy.options.compression] : this.identifyCompressionEnabled ? "identify" : "none"}`
|
|
626
678
|
]);
|
|
627
|
-
const
|
|
679
|
+
const data = {
|
|
628
680
|
token: this.strategy.options.token,
|
|
629
681
|
properties: this.strategy.options.identifyProperties,
|
|
630
682
|
intents: this.strategy.options.intents,
|
|
631
|
-
compress: this.
|
|
683
|
+
compress: this.identifyCompressionEnabled,
|
|
632
684
|
shard: [this.id, this.strategy.options.shardCount]
|
|
633
685
|
};
|
|
634
686
|
if (this.strategy.options.largeThreshold) {
|
|
635
|
-
|
|
687
|
+
data.large_threshold = this.strategy.options.largeThreshold;
|
|
636
688
|
}
|
|
637
689
|
if (this.strategy.options.initialPresence) {
|
|
638
|
-
|
|
690
|
+
data.presence = this.strategy.options.initialPresence;
|
|
639
691
|
}
|
|
640
692
|
await this.send({
|
|
641
693
|
op: import_v102.GatewayOpcodes.Identify,
|
|
642
|
-
|
|
694
|
+
// eslint-disable-next-line id-length
|
|
695
|
+
d: data
|
|
643
696
|
});
|
|
644
697
|
await this.waitForEvent("ready" /* Ready */, this.strategy.options.readyTimeout);
|
|
645
698
|
}
|
|
@@ -654,6 +707,7 @@ var WebSocketShard = class extends import_async_event_emitter.AsyncEventEmitter
|
|
|
654
707
|
this.replayedEvents = 0;
|
|
655
708
|
return this.send({
|
|
656
709
|
op: import_v102.GatewayOpcodes.Resume,
|
|
710
|
+
// eslint-disable-next-line id-length
|
|
657
711
|
d: {
|
|
658
712
|
token: this.strategy.options.token,
|
|
659
713
|
seq: session.sequence,
|
|
@@ -668,11 +722,18 @@ var WebSocketShard = class extends import_async_event_emitter.AsyncEventEmitter
|
|
|
668
722
|
const session = await this.strategy.retrieveSessionInfo(this.id);
|
|
669
723
|
await this.send({
|
|
670
724
|
op: import_v102.GatewayOpcodes.Heartbeat,
|
|
725
|
+
// eslint-disable-next-line id-length
|
|
671
726
|
d: session?.sequence ?? null
|
|
672
727
|
});
|
|
673
728
|
this.lastHeartbeatAt = Date.now();
|
|
674
729
|
this.isAck = false;
|
|
675
730
|
}
|
|
731
|
+
parseInflateResult(result) {
|
|
732
|
+
if (!result) {
|
|
733
|
+
return null;
|
|
734
|
+
}
|
|
735
|
+
return JSON.parse(typeof result === "string" ? result : this.textDecoder.decode(result));
|
|
736
|
+
}
|
|
676
737
|
async unpackMessage(data, isBinary) {
|
|
677
738
|
if (!isBinary) {
|
|
678
739
|
try {
|
|
@@ -682,9 +743,10 @@ var WebSocketShard = class extends import_async_event_emitter.AsyncEventEmitter
|
|
|
682
743
|
}
|
|
683
744
|
}
|
|
684
745
|
const decompressable = new Uint8Array(data);
|
|
685
|
-
if (this.
|
|
686
|
-
return new Promise((resolve2, reject) => {
|
|
687
|
-
|
|
746
|
+
if (this.identifyCompressionEnabled) {
|
|
747
|
+
return new Promise(async (resolve2, reject) => {
|
|
748
|
+
const zlib = await getNativeZlib();
|
|
749
|
+
zlib.inflate(decompressable, { chunkSize: 65535 }, (err, result) => {
|
|
688
750
|
if (err) {
|
|
689
751
|
reject(err);
|
|
690
752
|
return;
|
|
@@ -693,30 +755,37 @@ var WebSocketShard = class extends import_async_event_emitter.AsyncEventEmitter
|
|
|
693
755
|
});
|
|
694
756
|
});
|
|
695
757
|
}
|
|
696
|
-
if (this.
|
|
697
|
-
const
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
}
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
758
|
+
if (this.transportCompressionEnabled) {
|
|
759
|
+
const flush = decompressable.length >= 4 && decompressable.at(-4) === 0 && decompressable.at(-3) === 0 && decompressable.at(-2) === 255 && decompressable.at(-1) === 255;
|
|
760
|
+
if (this.nativeInflate) {
|
|
761
|
+
this.nativeInflate.write(decompressable, "binary");
|
|
762
|
+
if (!flush) {
|
|
763
|
+
return null;
|
|
764
|
+
}
|
|
765
|
+
const [result] = await (0, import_node_events2.once)(this.nativeInflate, "data");
|
|
766
|
+
return this.parseInflateResult(result);
|
|
767
|
+
} else if (this.zLibSyncInflate) {
|
|
768
|
+
const zLibSync = await getZlibSync();
|
|
769
|
+
this.zLibSyncInflate.push(import_node_buffer.Buffer.from(decompressable), flush ? zLibSync.Z_SYNC_FLUSH : zLibSync.Z_NO_FLUSH);
|
|
770
|
+
if (this.zLibSyncInflate.err) {
|
|
771
|
+
this.emit("error" /* Error */, {
|
|
772
|
+
error: new Error(
|
|
773
|
+
`${this.zLibSyncInflate.err}${this.zLibSyncInflate.msg ? `: ${this.zLibSyncInflate.msg}` : ""}`
|
|
774
|
+
)
|
|
775
|
+
});
|
|
776
|
+
}
|
|
777
|
+
if (!flush) {
|
|
778
|
+
return null;
|
|
779
|
+
}
|
|
780
|
+
const { result } = this.zLibSyncInflate;
|
|
781
|
+
return this.parseInflateResult(result);
|
|
712
782
|
}
|
|
713
|
-
return JSON.parse(typeof result === "string" ? result : this.textDecoder.decode(result));
|
|
714
783
|
}
|
|
715
784
|
this.debug([
|
|
716
785
|
"Received a message we were unable to decompress",
|
|
717
786
|
`isBinary: ${isBinary.toString()}`,
|
|
718
|
-
`
|
|
719
|
-
`inflate: ${
|
|
787
|
+
`identifyCompressionEnabled: ${this.identifyCompressionEnabled.toString()}`,
|
|
788
|
+
`inflate: ${this.transportCompressionEnabled ? CompressionMethod[this.strategy.options.compression] : "none"}`
|
|
720
789
|
]);
|
|
721
790
|
return null;
|
|
722
791
|
}
|
|
@@ -925,7 +994,7 @@ var WebSocketShard = class extends import_async_event_emitter.AsyncEventEmitter
|
|
|
925
994
|
}
|
|
926
995
|
debug(messages) {
|
|
927
996
|
const message = `${messages[0]}${messages.length > 1 ? `
|
|
928
|
-
${messages.slice(1).map((
|
|
997
|
+
${messages.slice(1).map((message2) => ` ${message2}`).join("\n")}` : ""}`;
|
|
929
998
|
this.emit("debug" /* Debug */, { message });
|
|
930
999
|
}
|
|
931
1000
|
};
|