import * as Vue from 'vue';
import { invariant } from '@tanstack/router-core';
import { useStore } from '@tanstack/vue-store';
import { isServer } from '@tanstack/router-core/isServer';
import { routeIdContext } from './matchContext';
import { useRouter } from './useRouter';
export function useMatch(opts) {
    const router = useRouter();
    // During SSR we render exactly once and do not need reactivity.
    // Avoid store subscriptions and pending/transition bookkeeping on the server.
    if (isServer ?? router.isServer) {
        const nearestRouteId = opts.from ? undefined : Vue.inject(routeIdContext);
        const matchStore = (opts.from ?? nearestRouteId)
            ? router.stores.getMatchStore(opts.from ?? nearestRouteId)
            : undefined;
        const match = matchStore?.get();
        if ((opts.shouldThrow ?? true) && !match) {
            if (process.env.NODE_ENV !== 'production') {
                throw new Error(`Invariant failed: Could not find ${opts.from ? `an active match from "${opts.from}"` : 'a nearest match!'}`);
            }
            invariant();
        }
        if (match === undefined) {
            return Vue.ref(undefined);
        }
        return Vue.ref(opts.select ? opts.select(match) : match);
    }
    // Set up reactive match value based on lookup strategy.
    let match;
    const nearestRouteId = Vue.inject(routeIdContext);
    if (opts.from) {
        // routeId case: subscribe to the stable per-route presentation atom.
        const matchStore = router.stores.getMatchStore(opts.from);
        match = useStore(matchStore);
    }
    else {
        // Nearest-match case: use the routeId from context for stable lookup.
        // The routeId is provided by the nearest Match component and doesn't
        // change for the component's lifetime, so the store is stable.
        if (nearestRouteId) {
            match = useStore(router.stores.getMatchStore(nearestRouteId));
        }
        else {
            // No route context — will fall through to error handling below
            match = Vue.ref(undefined);
        }
    }
    const ownsMatch = nearestRouteId !== undefined &&
        (opts.from ?? nearestRouteId) === nearestRouteId;
    let lastOwnedMatch;
    const result = Vue.computed(() => {
        if (match.value !== undefined && ownsMatch) {
            lastOwnedMatch = match.value;
        }
        const selectedMatch = match.value ?? lastOwnedMatch;
        if (selectedMatch === undefined) {
            if (opts.shouldThrow ?? true) {
                if (process.env.NODE_ENV !== 'production') {
                    throw new Error(`Invariant failed: Could not find ${opts.from ? `an active match from "${opts.from}"` : 'a nearest match!'}`);
                }
                invariant();
            }
            return undefined;
        }
        return opts.select ? opts.select(selectedMatch) : selectedMatch;
    });
    // Keep eager throw behavior for setups that call useMatch for side effects only.
    result.value;
    return result;
}
//# sourceMappingURL=useMatch.jsx.map