@koordinates/xstate-tree
Version:
Build UIs with Actors using xstate and React
145 lines (144 loc) • 4.42 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.toJSON = exports.mergeMeta = exports.isNil = exports.isEqual = exports.difference = exports.assert = exports.assertIsDefined = exports.delay = void 0;
function delay(ms = 0) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
exports.delay = delay;
function assertIsDefined(val, msg) {
if (val === undefined || val === null) {
throw new Error(`Expected 'val' to be defined, but received ${val} ${msg ? `(${msg})` : ""}`);
}
}
exports.assertIsDefined = assertIsDefined;
function assert(value, msg) {
if (typeof expect !== "undefined") {
if (value !== true && msg) {
console.error(msg);
}
expect(value).toEqual(true);
}
else if (value !== true) {
if (msg) {
console.error(msg);
}
throw new Error("assertion failed");
}
}
exports.assert = assert;
function difference(a, b) {
const result = {};
for (const key in b) {
if (!a.hasOwnProperty(key)) {
result[key] = b[key];
}
else if (Array.isArray(b[key]) && Array.isArray(a[key])) {
if (JSON.stringify(b[key]) !== JSON.stringify(a[key])) {
result[key] = b[key];
}
}
else if (typeof b[key] === "object" && typeof a[key] === "object") {
const value = difference(a[key], b[key]);
if (Object.keys(value).length > 0) {
result[key] = value;
}
}
else if (b[key] !== a[key]) {
result[key] = b[key];
}
}
return result;
}
exports.difference = difference;
/*
* @private
*
* Check if two objects or arrays are equal
* (c) 2021 Chris Ferdinandi, MIT License, https://gomakethings.com
* @param {*} obj1 The first item
* @param {*} obj2 The second item
* @return {Boolean} Returns true if they're equal in value
*/
function isEqual(obj1, obj2) {
/**
* More accurately check the type of a JavaScript object
* @param {Object} obj The object
* @return {String} The object type
*/
function getType(obj) {
return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();
}
function areArraysEqual() {
if (obj1.length !== obj2.length)
return false;
for (let i = 0; i < obj1.length; i++) {
if (!isEqual(obj1[i], obj2[i]))
return false;
}
return true;
}
function areObjectsEqual() {
if (Object.keys(obj1).length !== Object.keys(obj2).length)
return false;
for (const key in obj1) {
if (Object.prototype.hasOwnProperty.call(obj1, key)) {
if (!isEqual(obj1[key], obj2[key]))
return false;
}
}
return true;
}
function areFunctionsEqual() {
return obj1.toString() === obj2.toString();
}
function arePrimitivesEqual() {
return obj1 === obj2;
}
const type = getType(obj1);
if (type !== getType(obj2))
return false;
if (type === "array")
return areArraysEqual();
if (type === "object")
return areObjectsEqual();
if (type === "function")
return areFunctionsEqual();
return arePrimitivesEqual();
}
exports.isEqual = isEqual;
function isNil(
// eslint-disable-next-line @rushstack/no-new-null
value) {
return value === null || value === undefined;
}
exports.isNil = isNil;
function mergeMeta(meta) {
return Object.keys(meta).reduce((acc, key) => {
const value = meta[key];
// Assuming each meta value is an object
Object.assign(acc, value);
return acc;
}, {});
}
exports.mergeMeta = mergeMeta;
function getCircularReplacer(stripKeys) {
const seen = new WeakSet();
return (key, value) => {
if (stripKeys.includes(key)) {
return;
}
if (typeof value === "object" && value !== null) {
if (seen.has(value)) {
// Circular reference found, discard key
return;
}
// Store value in our set
seen.add(value);
}
return value;
};
}
function toJSON(value, stripKeys = []) {
return JSON.parse(JSON.stringify(value, getCircularReplacer(stripKeys)));
}
exports.toJSON = toJSON;