@shgysk8zer0/polyfills 0.2.8 → 0.3.0
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/CHANGELOG.md +14 -0
- package/Record.js +12 -2
- package/Tuple.js +90 -51
- package/all.min.js +13 -13
- package/all.min.js.map +1 -1
- package/iterator.js +276 -160
- package/legacy/set.js +72 -0
- package/package.json +1 -1
- package/set.js +73 -59
package/iterator.js
CHANGED
|
@@ -1,197 +1,313 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @see https://github.com/tc39/proposal-iterator-helpers
|
|
6
|
-
* @TODO implement `flat()`
|
|
7
|
-
* @TODO implement `flatMap()`
|
|
8
|
-
* @TODO implement `from()`
|
|
9
|
-
*/
|
|
10
|
-
if (! ('Iterator' in globalThis)) {
|
|
11
|
-
globalThis.Iterator = {
|
|
12
|
-
'prototype': Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]())),
|
|
13
|
-
};
|
|
14
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* @see https://github.com/tc39/proposal-iterator-helpers
|
|
3
|
+
*/
|
|
15
4
|
|
|
16
|
-
|
|
5
|
+
const supported = 'Iterator' in globalThis;
|
|
17
6
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
7
|
+
const IteratorPrototype = supported
|
|
8
|
+
? Object.getPrototypeOf(globalThis.Iterator)
|
|
9
|
+
: Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()));
|
|
10
|
+
|
|
11
|
+
const Iterator = supported
|
|
12
|
+
? globalThis.Iterator
|
|
13
|
+
: (proto => {
|
|
14
|
+
class Iterator {
|
|
15
|
+
[Symbol.iterator]() {
|
|
16
|
+
return this;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
Object.setPrototypeOf(Iterator, proto);
|
|
21
|
+
|
|
22
|
+
return Iterator;
|
|
23
|
+
})(IteratorPrototype);
|
|
24
|
+
|
|
25
|
+
if (! (Iterator.range instanceof Function)) {
|
|
26
|
+
Iterator.range = function range(start, end, option) {
|
|
27
|
+
if (typeof option === 'number' || typeof option === 'bigint') {
|
|
28
|
+
return Iterator.range(start, end, { step: option });
|
|
29
|
+
} else if (typeof option !== 'object' || Object.is(option, null)) {
|
|
30
|
+
return Iterator.range(start, end, {});
|
|
31
|
+
} else {
|
|
32
|
+
const {
|
|
33
|
+
// Default to +/-, Number/BigInt based on start & end
|
|
34
|
+
step = typeof start === 'number'
|
|
35
|
+
? start < end ? 1 : -1
|
|
36
|
+
: start < end ? 1n : -1n,
|
|
37
|
+
inclusive = false,
|
|
38
|
+
} = option;
|
|
39
|
+
|
|
40
|
+
if (typeof start !== 'number' && typeof start !== 'bigint') {
|
|
41
|
+
throw new TypeError('Start must be a number');
|
|
42
|
+
} else if (Number.isNaN(start)) {
|
|
43
|
+
throw new RangeError('Invalid start');
|
|
44
|
+
} else if (typeof end !== 'number' && typeof end !== 'bigint') {
|
|
45
|
+
throw new TypeError('End must be a number');
|
|
46
|
+
} else if (Number.isNaN(end)) {
|
|
47
|
+
throw new RangeError('Invalid end');
|
|
48
|
+
} else if (typeof step !== 'number' && typeof step !== 'bigint') {
|
|
49
|
+
throw new TypeError('Step must be a number');
|
|
50
|
+
} else if (Number.isNaN(step)) {
|
|
51
|
+
throw new RangeError('Invalid step');
|
|
52
|
+
} else if (step === 0) {
|
|
53
|
+
throw new RangeError('Step must not be 0');
|
|
54
|
+
} else if ((step < 0 && start < end) || (step > 0 && start > end)) {
|
|
55
|
+
return;
|
|
56
|
+
} else if (inclusive) {
|
|
57
|
+
let n = start;
|
|
58
|
+
if (step > 0) {
|
|
59
|
+
return Iterator.from({
|
|
60
|
+
next() {
|
|
61
|
+
const ret = n <= end ? { value: n, done: false } : { done: true };
|
|
62
|
+
n+= step;
|
|
63
|
+
return ret;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
} else {
|
|
67
|
+
return Iterator.from({
|
|
68
|
+
next() {
|
|
69
|
+
const ret = n >= end ? { value: n, done: false } : { done: true };
|
|
70
|
+
n+= step;
|
|
71
|
+
return ret;
|
|
72
|
+
}
|
|
73
|
+
});
|
|
27
74
|
}
|
|
28
75
|
} else {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
if (typeof start !== 'number' && typeof start !== 'bigint') {
|
|
38
|
-
throw new TypeError('Start must be a number');
|
|
39
|
-
} else if (Number.isNaN(start)) {
|
|
40
|
-
throw new RangeError('Invalid start');
|
|
41
|
-
} else if (typeof end !== 'number' && typeof end !== 'bigint') {
|
|
42
|
-
throw new TypeError('End must be a number');
|
|
43
|
-
} else if (Number.isNaN(end)) {
|
|
44
|
-
throw new RangeError('Invalid end');
|
|
45
|
-
} else if (typeof step !== 'number' && typeof step !== 'bigint') {
|
|
46
|
-
throw new TypeError('Step must be a number');
|
|
47
|
-
} else if (Number.isNaN(step)) {
|
|
48
|
-
throw new RangeError('Invalid step');
|
|
49
|
-
} else if (step === 0) {
|
|
50
|
-
throw new RangeError('Step must not be 0');
|
|
51
|
-
} else if ((step < 0 && start < end) || (step > 0 && start > end)) {
|
|
52
|
-
return;
|
|
53
|
-
} else if (inclusive) {
|
|
54
|
-
if (step > 0) {
|
|
55
|
-
for (let n = start; n <= end; n+= step) {
|
|
56
|
-
yield n;
|
|
57
|
-
}
|
|
58
|
-
} else {
|
|
59
|
-
for (let n = start; n >= end; n+= step) {
|
|
60
|
-
yield n;
|
|
76
|
+
let n = start;
|
|
77
|
+
|
|
78
|
+
if (step > 0) {
|
|
79
|
+
return Iterator.from({
|
|
80
|
+
next() {
|
|
81
|
+
const ret = n < end ? { value: n, done: false } : { done: true };
|
|
82
|
+
n+= step;
|
|
83
|
+
return ret;
|
|
61
84
|
}
|
|
62
|
-
}
|
|
85
|
+
});
|
|
63
86
|
} else {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
87
|
+
let n = start;
|
|
88
|
+
|
|
89
|
+
return Iterator.from({
|
|
90
|
+
next() {
|
|
91
|
+
const ret = n > end ? { value: n, done: false } : { done: true };
|
|
92
|
+
n+= step;
|
|
93
|
+
return ret;
|
|
71
94
|
}
|
|
72
|
-
}
|
|
95
|
+
});
|
|
73
96
|
}
|
|
74
97
|
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
}
|
|
77
101
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
102
|
+
if (! (IteratorPrototype[Symbol.toStringTag])) {
|
|
103
|
+
IteratorPrototype[Symbol.toStringTag] = 'Iterator';
|
|
104
|
+
}
|
|
81
105
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
106
|
+
if (! (IteratorPrototype.take instanceof Function)) {
|
|
107
|
+
IteratorPrototype.take = function take(limit) {
|
|
108
|
+
let n = 0;
|
|
109
|
+
const iter = this;
|
|
85
110
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
111
|
+
return Iterator.from({
|
|
112
|
+
next() {
|
|
113
|
+
if (n++ >= limit) {
|
|
114
|
+
return { done: true };
|
|
89
115
|
} else {
|
|
90
|
-
|
|
116
|
+
return iter.next();
|
|
91
117
|
}
|
|
92
118
|
}
|
|
93
|
-
};
|
|
94
|
-
}
|
|
119
|
+
});
|
|
120
|
+
};
|
|
121
|
+
}
|
|
95
122
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
123
|
+
if (! (IteratorPrototype.drop instanceof Function)) {
|
|
124
|
+
IteratorPrototype.drop = function drop(limit) {
|
|
125
|
+
for (let n = 0; n < limit; n++) {
|
|
126
|
+
const { done } = this.next();
|
|
127
|
+
|
|
128
|
+
if (done) {
|
|
129
|
+
break;
|
|
103
130
|
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
131
|
+
}
|
|
106
132
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
};
|
|
111
|
-
}
|
|
133
|
+
return this;
|
|
134
|
+
};
|
|
135
|
+
}
|
|
112
136
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
};
|
|
119
|
-
}
|
|
137
|
+
if (! (IteratorPrototype.toArray instanceof Function)) {
|
|
138
|
+
IteratorPrototype.toArray = function toArray() {
|
|
139
|
+
return Array.from(this);
|
|
140
|
+
};
|
|
141
|
+
}
|
|
120
142
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
143
|
+
if (! (IteratorPrototype.forEach instanceof Function)) {
|
|
144
|
+
IteratorPrototype.forEach = function forEach(callback) {
|
|
145
|
+
for (const item of this) {
|
|
146
|
+
callback.call(this, item);
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (! (IteratorPrototype.flatMap instanceof Function)) {
|
|
152
|
+
IteratorPrototype.flatMap = function flatMap(mapper) {
|
|
153
|
+
const iter = this;
|
|
154
|
+
let cur = this.next();
|
|
155
|
+
|
|
156
|
+
const getSubIter = ({ value, done = true } = {}) => {
|
|
157
|
+
return done
|
|
158
|
+
? Iterator.from({
|
|
159
|
+
next() {
|
|
160
|
+
return { done: true };
|
|
161
|
+
}
|
|
162
|
+
})
|
|
163
|
+
: Iterator.from(mapper.call(iter, value));
|
|
126
164
|
};
|
|
127
|
-
}
|
|
128
165
|
|
|
129
|
-
|
|
130
|
-
Iterator.prototype.reduce = function reduce(callback, initialValue) {
|
|
131
|
-
let current = typeof initialValue === 'undefined' ? this.next().value : initialValue;
|
|
166
|
+
let sub = getSubIter(cur);
|
|
132
167
|
|
|
133
|
-
|
|
134
|
-
|
|
168
|
+
return Iterator.from({
|
|
169
|
+
next() {
|
|
170
|
+
const { value, done = true } = sub.next();
|
|
171
|
+
|
|
172
|
+
if (cur.done && done) {
|
|
173
|
+
return { done: true };
|
|
174
|
+
} else if (! done) {
|
|
175
|
+
return { value, done };
|
|
176
|
+
} else if (! cur.done) {
|
|
177
|
+
cur = iter.next();
|
|
178
|
+
sub = getSubIter(cur);
|
|
179
|
+
return sub.next();
|
|
180
|
+
} else {
|
|
181
|
+
return { done: true };
|
|
182
|
+
}
|
|
135
183
|
}
|
|
184
|
+
});
|
|
136
185
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (! (IteratorPrototype.map instanceof Function)) {
|
|
190
|
+
IteratorPrototype.map = function map(callback) {
|
|
191
|
+
const iter = this;
|
|
192
|
+
|
|
193
|
+
return Iterator.from({
|
|
194
|
+
next() {
|
|
195
|
+
const { done, value } = iter.next();
|
|
140
196
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
yield item;
|
|
197
|
+
if (done) {
|
|
198
|
+
return { done };
|
|
199
|
+
} else {
|
|
200
|
+
return { value: callback.call(iter, value), done: false };
|
|
146
201
|
}
|
|
147
202
|
}
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
203
|
+
});
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (! (IteratorPrototype.reduce instanceof Function)) {
|
|
208
|
+
IteratorPrototype.reduce = function reduce(callback, initialValue) {
|
|
209
|
+
let current = typeof initialValue === 'undefined' ? this.next().value : initialValue;
|
|
210
|
+
|
|
211
|
+
for (const item of this) {
|
|
212
|
+
current = callback.call(this, current, item);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return current;
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (! (IteratorPrototype.filter instanceof Function)) {
|
|
220
|
+
IteratorPrototype.filter = function filter(callback) {
|
|
221
|
+
const iter = this;
|
|
222
|
+
let done = false;
|
|
223
|
+
let value = undefined;
|
|
224
|
+
|
|
225
|
+
return Iterator.from({
|
|
226
|
+
next() {
|
|
227
|
+
while (! done) {
|
|
228
|
+
const cur = iter.next();
|
|
229
|
+
done = cur.done;
|
|
230
|
+
|
|
231
|
+
if (done) {
|
|
232
|
+
break;
|
|
233
|
+
} else if (callback.call(iter, cur.value)) {
|
|
234
|
+
value = cur.value;
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
158
237
|
}
|
|
238
|
+
|
|
239
|
+
return { done, value };
|
|
159
240
|
}
|
|
241
|
+
});
|
|
242
|
+
};
|
|
243
|
+
}
|
|
160
244
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
for (const item of this) {
|
|
169
|
-
if (! callback(item)) {
|
|
170
|
-
retVal = false;
|
|
171
|
-
break;
|
|
172
|
-
}
|
|
245
|
+
if (! (IteratorPrototype.some instanceof Function)) {
|
|
246
|
+
IteratorPrototype.some = function some(callback) {
|
|
247
|
+
let retVal = false;
|
|
248
|
+
for (const item of this) {
|
|
249
|
+
if (callback.call(this, item)) {
|
|
250
|
+
retVal = true;
|
|
251
|
+
break;
|
|
173
252
|
}
|
|
253
|
+
}
|
|
174
254
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
255
|
+
return retVal;
|
|
256
|
+
};
|
|
257
|
+
}
|
|
178
258
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
259
|
+
if (! (IteratorPrototype.every instanceof Function)) {
|
|
260
|
+
IteratorPrototype.every = function every(callback) {
|
|
261
|
+
let retVal = true;
|
|
262
|
+
for (const item of this) {
|
|
263
|
+
if (! callback.call(this, item)) {
|
|
264
|
+
retVal = false;
|
|
265
|
+
break;
|
|
185
266
|
}
|
|
186
|
-
}
|
|
187
|
-
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
return retVal;
|
|
270
|
+
};
|
|
271
|
+
}
|
|
188
272
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
273
|
+
if (! (IteratorPrototype.find instanceof Function)) {
|
|
274
|
+
IteratorPrototype.find = function find(callback) {
|
|
275
|
+
for (const item of this) {
|
|
276
|
+
if (callback.call(this, item)) {
|
|
277
|
+
return item;
|
|
194
278
|
}
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
}
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
if (! (IteratorPrototype.indexed instanceof Function)) {
|
|
284
|
+
IteratorPrototype.indexed = function indexed() {
|
|
285
|
+
let n = 0;
|
|
286
|
+
return this.map(item => [n++, item]);
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
if (! (Iterator.from instanceof Function)) {
|
|
291
|
+
Iterator.from = function from(obj) {
|
|
292
|
+
if (typeof obj !== 'object' || obj === null) {
|
|
293
|
+
throw new TypeError('Not an object.');
|
|
294
|
+
} else if (obj.next instanceof Function) {
|
|
295
|
+
const iter = Object.create(IteratorPrototype, {
|
|
296
|
+
'next': {
|
|
297
|
+
enumerable: true,
|
|
298
|
+
configurable: false,
|
|
299
|
+
writable: false,
|
|
300
|
+
value: (...args) => obj.next(...args),
|
|
301
|
+
},
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
return iter;
|
|
305
|
+
} else if(obj[Symbol.iterator] instanceof Function) {
|
|
306
|
+
return Iterator.from(obj[Symbol.iterator]());
|
|
307
|
+
}
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if (! supported) {
|
|
312
|
+
globalThis.Iterator = Iterator;
|
|
313
|
+
}
|
package/legacy/set.js
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
if (! ('Set' in globalThis)) {
|
|
2
|
+
globalThis.Set = class Set {
|
|
3
|
+
#items = [];
|
|
4
|
+
|
|
5
|
+
constructor(items) {
|
|
6
|
+
Array.from(items).forEach(item => this.add(item));
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
[Symbol.iterator]() {
|
|
10
|
+
return this.#items.values();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
get [Symbol.toStringTag]() {
|
|
14
|
+
return 'Set';
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
get size() {
|
|
18
|
+
return this.#items.length;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
add(item) {
|
|
22
|
+
if (! this.has(item)){
|
|
23
|
+
this.#items.push(item);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return this;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
delete(item) {
|
|
30
|
+
const index = this.#items.indexOf(item);
|
|
31
|
+
|
|
32
|
+
if (index !== -1) {
|
|
33
|
+
this.#items = this.#items.slice(0, index).concat(this.#items.slice(index + 1));
|
|
34
|
+
return true;
|
|
35
|
+
} else {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
has(item) {
|
|
41
|
+
return this.#items.includes(item);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
clear() {
|
|
45
|
+
this.#items = [];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
keys() {
|
|
49
|
+
return this[Symbol.iterator]();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
values() {
|
|
53
|
+
return this[Symbol.iterator]();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
entries() {
|
|
57
|
+
return this.keys().map(item => [item, item]);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
forEach(callbackFn, thisArg) {
|
|
61
|
+
if (typeof thisArg === 'undefined') {
|
|
62
|
+
for (const value of this) {
|
|
63
|
+
callbackFn.call(this, value, value, this);
|
|
64
|
+
}
|
|
65
|
+
} else {
|
|
66
|
+
for (const value of this) {
|
|
67
|
+
callbackFn.call(thisArg, value, value, this);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
}
|