import { atom } from 'recoil';
import { isDerivedVariable } from '../../types';
import { atomRegistry, getRegistryKey } from './store';
/**
 * Get a trigger index for a variable from the atom registry, registering it if not already registered
 *
 * @param variable variable to register trigger for
 */
export function getOrRegisterTrigger(variable) {
    const triggerKey = getRegistryKey(variable, 'trigger');
    if (!atomRegistry.has(triggerKey)) {
        atomRegistry.set(triggerKey, atom({
            default: {
                force_key: null,
                inc: 0,
            },
            key: triggerKey,
        }));
    }
    return atomRegistry.get(triggerKey);
}
/**
 * Resolve current trigger index value for a variable from the atom registry.
 * If the atom is not registered, returns default values.
 */
export function resolveTriggerStatic(triggerAtom, snapshot) {
    if (!triggerAtom) {
        return {
            force_key: null,
            inc: 0,
        };
    }
    return snapshot.getLoadable(triggerAtom).valueOrThrow();
}
/**
 * Built a flat list of triggers, preserving information about the position of each trigger in the variable tree
 *
 * @param variables Array of variables to analyze
 * @returns list of triggers, with information about the variable that owns each trigger
 */
export function buildTriggerList(variables) {
    const triggers = [];
    function walk(vars, path) {
        for (const [idx, variable] of vars.entries()) {
            if (isDerivedVariable(variable)) {
                const varPath = [...path, String(idx)];
                // register trigger itself
                triggers.push({
                    path: varPath,
                    variable,
                });
                // register triggers for nested variables
                // NOTE: path will be values since we map into ResolvedXVariables
                walk(variable.variables, [...varPath, 'values']);
            }
        }
    }
    walk(variables, []);
    return triggers;
}
/**
 * Recursively register triggers in the list of dependant variables using a pre-built trigger list
 *
 * @param triggerList flat list of triggers to register
 * @param registerFunc register function to run
 * @param triggerMap optional pre-built trigger map for efficiency
 */
export function registerChildTriggers(triggerList, registerFunc) {
    return triggerList.map((triggerInfo) => {
        if (isDerivedVariable(triggerInfo.variable)) {
            const triggerIndex = getOrRegisterTrigger(triggerInfo.variable);
            return registerFunc(triggerIndex);
        }
        throw new Error('Invalid trigger variable type');
    });
}
//# sourceMappingURL=triggers.js.map