export function mergePipelineCallbacks(user, added) {
    return mergeCallbacks(user, added);
}
export function mergeExperimentCallbacks(user, added) {
    return mergeCallbacks(user, added);
}
export function mergeLoopCallbacks(user, added) {
    const merged = mergeCallbacks(user, added);
    if (user?.runRole && added?.runRole && merged) {
        merged.runRole = (role, name, run) => added.runRole(role, name, () => user.runRole(role, name, run));
    }
    return merged;
}
function mergeCallbacks(user, added) {
    if (!user) {
        return added;
    }
    if (!added) {
        return user;
    }
    const userCallbacks = user;
    const addedCallbacks = added;
    const result = {};
    const keys = new Set([...Object.keys(user), ...Object.keys(added)]);
    for (const key of keys) {
        const userCallback = userCallbacks[key];
        const addedCallback = addedCallbacks[key];
        if (userCallback && addedCallback) {
            result[key] = function mergedCallback(...args) {
                const userResult = userCallback.apply(this, args);
                try {
                    const addedResult = addedCallback.apply(this, args);
                    if (isPromiseLike(addedResult)) {
                        void addedResult.catch((error) => {
                            console.warn(`Added callback ${key} failed`, error);
                        });
                    }
                }
                catch (error) {
                    console.warn(`Added callback ${key} failed`, error);
                }
                return userResult;
            };
            continue;
        }
        result[key] = userCallback ?? addedCallback;
    }
    return result;
}
function isPromiseLike(value) {
    return Boolean(value && typeof value === "object" && "catch" in value && typeof value.catch === "function");
}
