• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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