// Copyright 2024 The Lynx Authors. All rights reserved.
// Licensed under the Apache License Version 2.0 that can be found in the
// LICENSE file in the root directory of this source tree.
import { getCurrentVNode, getOwnerStack } from './snapshot/debug/component-stack.js';
/* v8 ignore start */
export const noop = () => { };
/* v8 ignore end */
export function isDirectOrDeepEqual(a, b) {
    if (a === b) {
        return true;
    }
    try {
        if (typeof a == 'object' && a !== null && typeof b == 'object' && b !== null
            && JSON.stringify(a) === JSON.stringify(b)) {
            return true;
        }
    }
    catch (error) {
        if (__DEV__ && /circular|cyclic/i.test(error.message)) {
            // JavaScript engines give this different errors name and messages:
            // PrimJS: "circular reference"
            // JavaScriptCore: "JSON.stringify cannot serialize cyclic structures"
            // V8: "Converting circular structure to JSON"
            const vnode = getCurrentVNode();
            if (vnode) {
                const stack = getOwnerStack(vnode);
                error.message += `\n\n${stack}`;
            }
        }
        throw error;
    }
    return false;
}
export function isEmptyObject(obj) {
    for (const _ in obj)
        return false;
    return true;
}
export function isSdkVersionGt(major, minor) {
    const lynxSdkVersion = SystemInfo.lynxSdkVersion ?? '1.0';
    const version = lynxSdkVersion.split('.');
    return Number(version[0]) > major || (Number(version[0]) == major && Number(version[1]) > minor);
}
export function pick(obj, keys) {
    const result = {};
    for (const key of keys) {
        if (key in obj) {
            result[key] = obj[key];
        }
    }
    return result;
}
export function maybePromise(value) {
    return (typeof value === 'object'
        && value !== null
        // @ts-expect-error the check is safe
        && typeof value.then === 'function');
}
export function getDisplayName(type) {
    return type.displayName ?? type.name;
}
export function hook(object, key, fn) {
    const oldFn = object[key];
    object[key] = function (...args) {
        return fn.call(this, oldFn, ...args);
    };
}
export const lynxQueueMicrotask = /* @__PURE__ */ (() => {
    if (lynx.queueMicrotask) {
        return (fn) => lynx.queueMicrotask(fn);
    }
    else if (typeof globalThis.Promise === 'function') {
        const resolved = globalThis.Promise.resolve();
        /* v8 ignore start */
        return (fn) => {
            // Schedule as a microtask, and surface exceptions like queueMicrotask would.
            resolved.then(fn).catch((err) => {
                setTimeout(() => {
                    throw err;
                }, 0);
            });
        };
    }
    else {
        // Fallback to macrotask when microtasks aren't available.
        return (fn) => {
            setTimeout(fn, 0);
        };
    }
    /* v8 ignore stop */
})();
//# sourceMappingURL=utils.js.map