"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isTraceableFunction = exports.ROOT = exports.withRunTree = exports.getCurrentRunTree = exports.AsyncLocalStorageProviderSingleton = void 0;
const run_trees_js_1 = require("../run_trees.cjs");
class MockAsyncLocalStorage {
    getStore() {
        return undefined;
    }
    run(_, callback) {
        return callback();
    }
}
const TRACING_ALS_KEY = Symbol.for("ls:tracing_async_local_storage");
const mockAsyncLocalStorage = new MockAsyncLocalStorage();
class AsyncLocalStorageProvider {
    getInstance() {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        return globalThis[TRACING_ALS_KEY] ?? mockAsyncLocalStorage;
    }
    initializeGlobalInstance(instance) {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        if (globalThis[TRACING_ALS_KEY] === undefined) {
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            globalThis[TRACING_ALS_KEY] = instance;
        }
    }
}
exports.AsyncLocalStorageProviderSingleton = new AsyncLocalStorageProvider();
/**
 * Return the current run tree from within a traceable-wrapped function.
 * Will throw an error if called outside of a traceable function.
 *
 * @returns The run tree for the given context.
 */
const getCurrentRunTree = () => {
    const runTree = exports.AsyncLocalStorageProviderSingleton.getInstance().getStore();
    if (!(0, run_trees_js_1.isRunTree)(runTree)) {
        throw new Error([
            "Could not get the current run tree.",
            "",
            "Please make sure you are calling this method within a traceable function or the tracing is enabled.",
        ].join("\n"));
    }
    return runTree;
};
exports.getCurrentRunTree = getCurrentRunTree;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function withRunTree(runTree, fn) {
    const storage = exports.AsyncLocalStorageProviderSingleton.getInstance();
    return new Promise((resolve, reject) => {
        storage.run(runTree, () => void Promise.resolve(fn()).then(resolve).catch(reject));
    });
}
exports.withRunTree = withRunTree;
exports.ROOT = Symbol.for("langsmith:traceable:root");
function isTraceableFunction(x
// eslint-disable-next-line @typescript-eslint/no-explicit-any
) {
    return typeof x === "function" && "langsmith:traceable" in x;
}
exports.isTraceableFunction = isTraceableFunction;
