BetterDiscordApp-v2/common/modules/iterable-weak-collections.js

172 lines
4.9 KiB
JavaScript

/**
* BetterDiscord Iterable Weak Collections
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import process from 'process';
export class IterableWeakMap extends WeakMap {
[Symbol.iterator]() {
return this.entries();
}
entries() {
return IterableWeakCollections.getWeakMapEntries(this).values();
}
keys() {
return IterableWeakCollections.getWeakMapEntries(this).map(e => e[0]).values();
}
values() {
return IterableWeakCollections.getWeakMapEntries(this).map(e => e[1]).values();
}
forEach(callback, thisArg) {
for (let [key, value] of this) {
callback.call(thisArg, value, key, this);
}
}
clear() {
for (let key of this.keys()) {
this.delete(key);
}
}
get size() {
return IterableWeakCollections.getWeakMapEntries(this).length;
}
get [Symbol.toStringTag]() {
return 'IterableWeakMap';
}
static get [Symbol.species]() {
return IterableWeakMap;
}
}
export class IterableWeakSet extends WeakSet {
[Symbol.iterator]() {
return this.values();
}
values() {
return IterableWeakCollections.getWeakSetValues(this).values();
}
forEach(callback, thisArg) {
for (let value of this) {
callback.call(thisArg, value, value, this);
}
}
clear() {
for (let value of this) {
this.delete(value);
}
}
get size() {
return IterableWeakCollections.getWeakSetValues(this).length;
}
static get [Symbol.species]() {
return IterableWeakSet;
}
}
export class IterableWeakCollections {
/**
* Returns a WeakMap's entries.
* @param {WeakMap} weakmap
* @return {Array}
*/
static getWeakMapEntries(wm) {
const keysAndValues = this._getWeakMapEntries(wm);
const entries = [];
while (keysAndValues.length) {
const key = keysAndValues.shift();
const value = keysAndValues.shift();
entries.push([key, value]);
}
return entries;
}
static mapFromWeakMap(wm) {
return new Map(this.getWeakMapEntries(wm));
}
/**
* Returns a WeakSet's values.
* @param {WeakSet} weakset
* @return {Array}
*/
static getWeakSetValues(ws) {
return this._getWeakSetValues(ws);
}
static setFromWeakSet(ws) {
return new Set(this.getWeakSetValues(ws));
}
static _init() {
this._natives_syntax = process.execArgv.some(s => /^--allow[-_]natives[-_]syntax$/.test(s));
// Use eval otherwise webpack will throw a syntax error
// eslint-disable-next-line no-eval
this._getWeakMapEntries = eval(`this._callWithNativesSyntax.bind(this, function (wm, max) {
// Retrieve all WeakMap instance key / value pairs up to \`max\`. \`max\` limits the
// number of key / value pairs returned. Make sure it is a positive number,
// otherwise V8 aborts. Passing through \`0\` returns all elements.
if (!(wm instanceof WeakMap)) throw new Error('weakmap must be an instance of WeakMap');
return %GetWeakMapEntries(wm, typeof max === 'number' && max > 0 ? max : 0);
}, this)`);
// eslint-disable-next-line no-eval
this._getWeakSetValues = eval(`this._callWithNativesSyntax.bind(this, function (ws, max) {
// Retrieve all WeakSet instance values up to \`max\`. \`max\` limits the
// number of values returned. Make sure it is a positive number,
// otherwise V8 aborts. Passing through \`0\` returns all elements.
if (!(ws instanceof WeakSet)) throw new Error('weakset must be an instance of WeakSet');
return %GetWeakSetValues(ws, typeof max === 'number' && max > 0 ? max : 0);
}, this)`);
}
static _callWithNativesSyntax(f, bind, ...args) {
const v8 = process.binding('v8');
// Enable natives syntax
v8.setFlagsFromString('--allow_natives_syntax');
try {
const r = f.apply(bind, args);
// Disable --allow_natives_syntax again unless it was explicitly
// specified on the command line
if (!this._natives_syntax) v8.setFlagsFromString('--noallow_natives_syntax');
return r;
} catch (err) {
// Disable --allow_natives_syntax again unless it was explicitly
// specified on the command line
if (!this._natives_syntax) v8.setFlagsFromString('--noallow_natives_syntax');
throw err;
}
}
}
IterableWeakCollections._callWithNativesSyntax(IterableWeakCollections._init, IterableWeakCollections);