@launchmenu/core
Version:
An environment for visual keyboard controlled applets
310 lines • 23.7 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ExtendedObject = void 0;
/**
* Some object related utils
*/
class ExtendedObject {
// Testing methods
/**
* Checks whether a passed object is a plain javascript object
* @param obj The object to perform the operation on
* @returns Whether or not the object is a plain javascipt object
*/
static isPlainObject(obj) {
// @ts-ignore
return obj && obj.__proto__ && obj.__proto__.constructor == Object;
}
// Mapping methods
/**
* Maps the values of an object to a new object
* @param obj The object to perform the operation on
* @param func The function to use for the mapping, where the params are value, key, and the return value is used as the new value
* @returns The object created as a mapping of the values of this object
*/
static mapValues(obj, func) {
// Get the keys of the this object
const keys = Object.keys(obj);
// Create an output object
const out = {};
// Go through all keys
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
// Call the passed func to map the value
const newValue = func(obj[key], key);
// Store the mapped value
out[key] = newValue;
}
// Return the output object
return out;
}
/**
* Maps the values of an object to a new object, alias for mapValues
* @param obj The object to perform the operation on
* @param func The function to use for the mapping, where the params are value, key, and the return value is used as the new value
* @returns The object created as a mapping of the values of this object
*/
static map(obj, func) {
return this.mapValues(obj, func);
}
/**
* Maps the keys of an object to a new object
* @param obj The object to perform the operation on
* @param func The function to use for the mapping, where the params are key, value, and the return value is used as the new key
* @returns The object created as a mapping of the keys of this object
*/
static mapKeys(obj, func) {
// Get the keys of the this object
const keys = Object.keys(obj);
// Create an output object
const out = {};
// Go through all keys
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
// Call the passed func to map the key
const newKey = func(key, obj[key]);
// Store the mapped key
out[newKey] = obj[key];
}
// Return the output object
return out;
}
/**
* Maps the keys and values of an object to a new object
* @param obj The object to perform the operation on
* @param func The function to use for the mapping, where the params are key, value, and the return value is an array with the key as the first index, and value as the second
* @returns The object created as a mapping of the keys and values of this object
*/
static mapPairs(obj, func) {
// Get the keys of the this object
const keys = Object.keys(obj);
// Create an output object
const out = {};
// Go through all keys
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
// Call the passed func to map the key and value
const [newKey, newValue] = func(key, obj[key]);
// Store the mapped key
out[newKey] = newValue;
}
// Return the output object
return out;
}
/**
* Creates an object from the given entry array
* @param entries The entries to create an object from
* @returns The resulting object
*/
static fromEntries(entries) {
const out = {};
entries.forEach(([key, value]) => {
out[key] = value;
});
return out;
}
/**
* Filters the some fields from the object
* @param obj The object to perform the operation on
* @param func The function to use to filter, where the params are value and key
* @returns The object created which contains all fields that the func returned true for
*/
static filter(obj, func) {
// Get the keys of the this object
const keys = Object.keys(obj);
// Create an output object
const out = {};
// Go through all keys
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
// Check if the field should be included
if (func(obj[key], key)) {
// Store the field in the output
out[key] = obj[key];
}
}
// Return the output object
return out;
}
/**
* Creates an object containing of the defined fields
* @param obj The object to perform the operation on
* @param fields A list of fields to include in the object
* @returns The object created which contains all specified fields
*/
static project(obj, fields) {
// Get the keys of the this object
const keys = Object.keys(obj);
// Create an output object
const out = {};
// Go through all keys
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
// Check if the field should be included
if (fields.indexOf(key) !== -1) {
// Store the field in the output
out[key] = obj[key];
}
}
// Return the output object
return out;
}
// Itarator methods
/**
* Calls the provided method on all key value pairs
* @param obj The object to perform the operation on
* @param func The function to call for each of the pairs, receives key and value as parameters
* @param recurse Whether or notto recurse on a child object, a function can be provided that will receive the key and value as parameters, and returns whether or not to recurse
* @param includeRecurseObj Whether the object that is recursed on should also be called on the function
* @param path The path to include to the callback of where we are at in the object
*/
static forEach(obj, func, recurse = false, includeRecurseObj = false, path = "") {
// Get the keys of the this object
const keys = Object.keys(obj);
// Go through all keys
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
const value = obj[key];
const p = (path ? path + "." : "") + key;
// Check if we should recurse
if (typeof recurse == "function"
? value instanceof Object && recurse(key, value, p, path)
: recurse && this.isPlainObject(value)) {
// Call the function
if (includeRecurseObj)
func(key, value, p, path);
// Recurse
this.forEach(value, func, recurse, includeRecurseObj, p);
}
else {
// Call the function
func(key, value, p, path);
}
}
}
/**
* Calls the provided method on all key value pairs that are available in each object
* @param objects The array of objects to perform the operation on
* @param func The function to call for each of the pairs, receives key and value as parameters
* @param recurse Whether or notto recurse on a child object, a function can be provided that will receive the key and value as parameters, and returns whether or not to recurse
* @param firstObjectLeading Whether the first object dictates the structure, I.e. if a subsequent object doesn't contain a substructure, it appears as if it does have the structured but is filled with undefined.
* @param path The path to include to the callback of where we are at in the object
*/
static forEachPaired(objects, func, recurse = false, firstObjectLeading = false, path = "") {
// Get the keys of the this object
const keys = Object.keys(objects[0]);
// Go through all keys
keyLoop: for (let i = 0; i < keys.length; i++) {
const key = keys[i];
// Check if the key is present in all objects
if (!firstObjectLeading)
for (let j = 1; j < objects.length; j++)
if (objects[j][key] === undefined)
continue keyLoop;
// Get the values for each of the objects
const values = objects.map(obj => (obj ? obj[key] : undefined));
const p = (path ? path + "." : "") + key;
// Check if all values are of type object
const isPlainObject = firstObjectLeading
? this.isPlainObject(values[0])
: values.reduce((cur, value) => cur & this.isPlainObject(value), true);
// Check if we should recurse
if (isPlainObject &&
recurse &&
(typeof recurse != "function" || recurse(key, values, p, path))) {
this.forEachPaired(values, func, recurse, firstObjectLeading, p);
}
else {
// Call the function
func(key, values, p, path);
}
}
}
// Modification methods
/**
* Merges two objects together
* @param obj1 The first object
* @param obj2 The second object (which takes precedence)
* @returns The merged objects
*/
static deepMerge(obj1, obj2) {
if (obj1 instanceof Object && obj2 instanceof Object) {
const obj = {};
Object.keys(obj1).forEach(key => {
if (!obj2[key])
obj[key] = obj1[key];
});
Object.keys(obj2).forEach(key => {
if (!obj1[key])
obj[key] = obj2[key];
});
Object.keys(obj1).forEach(key => {
if (obj1[key] && obj2[key])
obj[key] = this.deepMerge(obj1[key], obj2[key]);
});
return obj;
}
else
return obj2;
}
// Comparison methods
/**
* Checks if the contents of object 1 and 2 are equal
* @param obj1 The first object
* @param obj2 The second object
* @param includeObjects Whether object difference should be taken into account
* @returns Whether or not the contents of the two objects are equivalent
*/
static equals(obj1, obj2, includeObjects = true) {
// Check if there are the same number of values present
const obj1Keys = Object.keys(obj1);
const obj2Keys = Object.keys(obj2);
if (obj1Keys.length != obj2Keys.length)
return false;
// Check if all values are equivalent
for (let i = 0; i < obj1Keys.length; i++) {
const key = obj1Keys[i];
// Values may only differ if they are objects
if ((typeof obj1[key] != "object" || includeObjects) &&
obj1[key] !== obj2[key])
return false;
}
return true;
}
/**
* Checks if the contents of object 1 and 2 are equal, including subobjects
* @param obj1 The first object
* @param obj2 The second object
* @param maxDepth The maximum depth to check
* @returns Whether or not the contents of the two objects are equivalent
*/
static deepEquals(obj1, obj2, maxDepth = Infinity) {
if (obj1 == obj2)
return true;
if (maxDepth == 0)
return false;
// Check if there are the same number of values present
const obj1Keys = Object.keys(obj1);
const obj2Keys = Object.keys(obj2);
if (obj1Keys.length != obj2Keys.length)
return false;
// Check if all values are equivalent
for (let i = 0; i < obj1Keys.length; i++) {
const key = obj1Keys[i];
if ((this.isPlainObject(obj1[key]) || obj1[key] instanceof Array) &&
(this.isPlainObject(obj2[key]) || obj2[key] instanceof Array)) {
// Recurse if object or array
if (!this.deepEquals(obj1[key], obj2[key], maxDepth - 1))
return false;
}
else {
// Check shallow equivalence otherwise
if (obj1[key] !== obj2[key])
return false;
}
}
return true;
}
}
exports.ExtendedObject = ExtendedObject;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRXh0ZW5kZWRPYmplY3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvRXh0ZW5kZWRPYmplY3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBRUE7O0dBRUc7QUFDSCxNQUFhLGNBQWM7SUFDdkIsa0JBQWtCO0lBQ2xCOzs7O09BSUc7SUFDSSxNQUFNLENBQUMsYUFBYSxDQUFDLEdBQVE7UUFDaEMsYUFBYTtRQUNiLE9BQU8sR0FBRyxJQUFJLEdBQUcsQ0FBQyxTQUFTLElBQUksR0FBRyxDQUFDLFNBQVMsQ0FBQyxXQUFXLElBQUksTUFBTSxDQUFDO0lBQ3ZFLENBQUM7SUFFRCxrQkFBa0I7SUFDbEI7Ozs7O09BS0c7SUFDSSxNQUFNLENBQUMsU0FBUyxDQUNuQixHQUFNLEVBQ04sSUFBMkM7UUFFM0Msa0NBQWtDO1FBQ2xDLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFFOUIsMEJBQTBCO1FBQzFCLE1BQU0sR0FBRyxHQUFHLEVBQTBCLENBQUM7UUFFdkMsc0JBQXNCO1FBQ3RCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQ2xDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUVwQix3Q0FBd0M7WUFDeEMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztZQUVyQyx5QkFBeUI7WUFDekIsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLFFBQVEsQ0FBQztTQUN2QjtRQUVELDJCQUEyQjtRQUMzQixPQUFPLEdBQVUsQ0FBQztJQUN0QixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSSxNQUFNLENBQUMsR0FBRyxDQUNiLEdBQU0sRUFDTixJQUEyQztRQUUzQyxPQUFPLElBQUksQ0FB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