compression.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.decompress = exports.compress = exports.uncompressibleCommands = exports.Compressor = void 0;
  4. const util_1 = require("util");
  5. const zlib = require("zlib");
  6. const constants_1 = require("../../constants");
  7. const deps_1 = require("../../deps");
  8. const error_1 = require("../../error");
  9. /** @public */
  10. exports.Compressor = Object.freeze({
  11. none: 0,
  12. snappy: 1,
  13. zlib: 2,
  14. zstd: 3
  15. });
  16. exports.uncompressibleCommands = new Set([
  17. constants_1.LEGACY_HELLO_COMMAND,
  18. 'saslStart',
  19. 'saslContinue',
  20. 'getnonce',
  21. 'authenticate',
  22. 'createUser',
  23. 'updateUser',
  24. 'copydbSaslStart',
  25. 'copydbgetnonce',
  26. 'copydb'
  27. ]);
  28. const ZSTD_COMPRESSION_LEVEL = 3;
  29. const zlibInflate = (0, util_1.promisify)(zlib.inflate.bind(zlib));
  30. const zlibDeflate = (0, util_1.promisify)(zlib.deflate.bind(zlib));
  31. let zstd;
  32. let Snappy = null;
  33. function loadSnappy() {
  34. if (Snappy == null) {
  35. const snappyImport = (0, deps_1.getSnappy)();
  36. if ('kModuleError' in snappyImport) {
  37. throw snappyImport.kModuleError;
  38. }
  39. Snappy = snappyImport;
  40. }
  41. return Snappy;
  42. }
  43. // Facilitate compressing a message using an agreed compressor
  44. async function compress(options, dataToBeCompressed) {
  45. const zlibOptions = {};
  46. switch (options.agreedCompressor) {
  47. case 'snappy': {
  48. Snappy ??= loadSnappy();
  49. return Snappy.compress(dataToBeCompressed);
  50. }
  51. case 'zstd': {
  52. loadZstd();
  53. if ('kModuleError' in zstd) {
  54. throw zstd['kModuleError'];
  55. }
  56. return zstd.compress(dataToBeCompressed, ZSTD_COMPRESSION_LEVEL);
  57. }
  58. case 'zlib': {
  59. if (options.zlibCompressionLevel) {
  60. zlibOptions.level = options.zlibCompressionLevel;
  61. }
  62. return zlibDeflate(dataToBeCompressed, zlibOptions);
  63. }
  64. default: {
  65. throw new error_1.MongoInvalidArgumentError(`Unknown compressor ${options.agreedCompressor} failed to compress`);
  66. }
  67. }
  68. }
  69. exports.compress = compress;
  70. // Decompress a message using the given compressor
  71. async function decompress(compressorID, compressedData) {
  72. if (compressorID !== exports.Compressor.snappy &&
  73. compressorID !== exports.Compressor.zstd &&
  74. compressorID !== exports.Compressor.zlib &&
  75. compressorID !== exports.Compressor.none) {
  76. throw new error_1.MongoDecompressionError(`Server sent message compressed using an unsupported compressor. (Received compressor ID ${compressorID})`);
  77. }
  78. switch (compressorID) {
  79. case exports.Compressor.snappy: {
  80. Snappy ??= loadSnappy();
  81. return Snappy.uncompress(compressedData, { asBuffer: true });
  82. }
  83. case exports.Compressor.zstd: {
  84. loadZstd();
  85. if ('kModuleError' in zstd) {
  86. throw zstd['kModuleError'];
  87. }
  88. return zstd.decompress(compressedData);
  89. }
  90. case exports.Compressor.zlib: {
  91. return zlibInflate(compressedData);
  92. }
  93. default: {
  94. return compressedData;
  95. }
  96. }
  97. }
  98. exports.decompress = decompress;
  99. /**
  100. * Load ZStandard if it is not already set.
  101. */
  102. function loadZstd() {
  103. if (!zstd) {
  104. zstd = (0, deps_1.getZstdLibrary)();
  105. }
  106. }
  107. //# sourceMappingURL=compression.js.map