-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
84 lines (64 loc) · 2.01 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
'use strict';
const {Readable} = require('stream');
const {build} = require('modernizr');
const inspectWithKind = require('inspect-with-kind');
const isPlainObject = require('lodash/isPlainObject');
const jsonStableStringifyWithoutJsonify = require('json-stable-stringify-without-jsonify');
const built = Symbol('built');
const read = Symbol('read');
const caches = new Map();
class ModernizrStream extends Readable {
#fullModernizrCode = null;
#emittedLength = 0;
constructor(...args) {
const argLen = args.length;
const [options = {}] = args;
if (argLen === 1) {
if (!isPlainObject(options)) {
const error = new TypeError(`Expected an <Object> to set modernizr-stream options, but got ${
inspectWithKind(options)
}.`);
error.code = 'ERR_INVALID_ARG_TYPE';
throw error;
}
} else if (argLen !== 0) {
const error = new RangeError(`Expected 0 or 1 argument (<Object>), but got ${argLen} arguments.`);
error.code = 'ERR_TOO_MANY_ARGS';
throw error;
}
super(options);
const cacheKey = jsonStableStringifyWithoutJsonify(options);
const cache = caches.get(cacheKey);
if (cache !== undefined) {
this.#fullModernizrCode = cache;
this.emit(built);
return;
}
build(options, code => {
const codeUint8Array = new TextEncoder().encode(code);
caches.set(cacheKey, codeUint8Array);
this.#fullModernizrCode = codeUint8Array;
this.emit(built);
});
}
// Replaceable with a private method `#read()` in the future
// https://github.com/tc39/proposal-private-methods
[read](size) {
const sliced = this.#fullModernizrCode.slice(this.#emittedLength, this.#emittedLength + size);
this.#emittedLength += sliced.length;
this.push(sliced);
if (this.#fullModernizrCode.length === this.#emittedLength) {
this.push(null);
}
}
_read(size) {
if (this.#fullModernizrCode === null) {
this.once(built, () => this[read](size));
return;
}
this[read](size);
}
}
module.exports = function modernizrStream(...args) {
return new ModernizrStream(...args);
};