1'use strict'; 2 3const { 4 ObjectDefineProperties, 5 Symbol, 6} = primordials; 7 8const { 9 codes: { 10 ERR_INVALID_ARG_VALUE, 11 ERR_INVALID_THIS, 12 }, 13} = require('internal/errors'); 14 15const { 16 newReadableWritablePairFromDuplex, 17} = require('internal/webstreams/adapters'); 18 19const { customInspect } = require('internal/webstreams/util'); 20 21const { 22 customInspectSymbol: kInspect, 23 kEnumerableProperty, 24} = require('internal/util'); 25 26let zlib; 27function lazyZlib() { 28 zlib ??= require('zlib'); 29 return zlib; 30} 31 32const kHandle = Symbol('kHandle'); 33const kTransform = Symbol('kTransform'); 34const kType = Symbol('kType'); 35 36/** 37 * @typedef {import('./readablestream').ReadableStream} ReadableStream 38 * @typedef {import('./writablestream').WritableStream} WritableStream 39 */ 40 41function isCompressionStream(value) { 42 return typeof value?.[kHandle] === 'object' && 43 value?.[kType] === 'CompressionStream'; 44} 45 46function isDecompressionStream(value) { 47 return typeof value?.[kHandle] === 'object' && 48 value?.[kType] === 'DecompressionStream'; 49} 50 51class CompressionStream { 52 /** 53 * @param {'deflate'|'gzip'} format 54 */ 55 constructor(format) { 56 this[kType] = 'CompressionStream'; 57 switch (format) { 58 case 'deflate': 59 this[kHandle] = lazyZlib().createDeflate(); 60 break; 61 case 'gzip': 62 this[kHandle] = lazyZlib().createGzip(); 63 break; 64 default: 65 throw new ERR_INVALID_ARG_VALUE('format', format); 66 } 67 this[kTransform] = newReadableWritablePairFromDuplex(this[kHandle]); 68 } 69 70 /** 71 * @readonly 72 * @type {ReadableStream} 73 */ 74 get readable() { 75 if (!isCompressionStream(this)) 76 throw new ERR_INVALID_THIS('CompressionStream'); 77 return this[kTransform].readable; 78 } 79 80 /** 81 * @readonly 82 * @type {WritableStream} 83 */ 84 get writable() { 85 if (!isCompressionStream(this)) 86 throw new ERR_INVALID_THIS('CompressionStream'); 87 return this[kTransform].writable; 88 } 89 90 [kInspect](depth, options) { 91 if (!isCompressionStream(this)) 92 throw new ERR_INVALID_THIS('CompressionStream'); 93 customInspect(depth, options, 'CompressionStream', { 94 readable: this[kTransform].readable, 95 writable: this[kTransform].writable, 96 }); 97 } 98} 99 100class DecompressionStream { 101 /** 102 * @param {'deflate'|'gzip'} format 103 */ 104 constructor(format) { 105 this[kType] = 'DecompressionStream'; 106 switch (format) { 107 case 'deflate': 108 this[kHandle] = lazyZlib().createInflate(); 109 break; 110 case 'gzip': 111 this[kHandle] = lazyZlib().createGunzip(); 112 break; 113 default: 114 throw new ERR_INVALID_ARG_VALUE('format', format); 115 } 116 this[kTransform] = newReadableWritablePairFromDuplex(this[kHandle]); 117 } 118 119 /** 120 * @readonly 121 * @type {ReadableStream} 122 */ 123 get readable() { 124 if (!isDecompressionStream(this)) 125 throw new ERR_INVALID_THIS('DecompressionStream'); 126 return this[kTransform].readable; 127 } 128 129 /** 130 * @readonly 131 * @type {WritableStream} 132 */ 133 get writable() { 134 if (!isDecompressionStream(this)) 135 throw new ERR_INVALID_THIS('DecompressionStream'); 136 return this[kTransform].writable; 137 } 138 139 [kInspect](depth, options) { 140 if (!isDecompressionStream(this)) 141 throw new ERR_INVALID_THIS('DecompressionStream'); 142 customInspect(depth, options, 'DecompressionStream', { 143 readable: this[kTransform].readable, 144 writable: this[kTransform].writable, 145 }); 146 } 147} 148 149ObjectDefineProperties(CompressionStream.prototype, { 150 readable: kEnumerableProperty, 151 writable: kEnumerableProperty, 152}); 153 154ObjectDefineProperties(DecompressionStream.prototype, { 155 readable: kEnumerableProperty, 156 writable: kEnumerableProperty, 157}); 158 159module.exports = { 160 CompressionStream, 161 DecompressionStream, 162}; 163