/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { debugAssert } from "@fluidframework/core-utils/internal";
/**
 * The current observer, if any.
 * @remarks
 * Set via {@link setObserver} as used by {@link withObservation}.
 * It should not be assigned in any other way.
 * @privateRemarks
 * This is exported directly as a property instead of via a getter for reduced overhead (less code, faster access) as this is used on some hot paths and its performance matters.
 * The case where this is undefined (no observation) is particularly important for performance as we do not want to regress code which is not using this feature very much.
 * Since it is not exported outside the package, this seems like a fine tradeoff, but could be reevaluated with some benchmarking if needed.
 */
export let currentObserver;
const observerStack = [];
function setObserver(newObserver) {
    observerStack.push(newObserver);
    currentObserver = newObserver;
}
function clearObserver() {
    debugAssert(() => observerStack.length > 0 || "Empty Observer stack on clear");
    const popped = observerStack.pop();
    debugAssert(() => popped === currentObserver || "Mismatched observer stack");
    currentObserver = observerStack[observerStack.length - 1];
}
/**
 * For the duration of `f`, pushes `newObserver` onto the observer stack, making it the {@link currentObserver}.
 */
export function withObservation(newObserver, f) {
    setObserver(newObserver);
    try {
        return f();
    }
    finally {
        clearObserver();
    }
}
//# sourceMappingURL=observer.js.map