import { removeItem } from 'motion-utils';
import { microtask } from '../frameloop/microtask.mjs';
import { startViewAnimation } from './start.mjs';

let builders = [];
let current = null;
function next() {
    current = null;
    const [nextBuilder] = builders;
    if (nextBuilder)
        start(nextBuilder);
}
function start(builder) {
    removeItem(builders, builder);
    current = builder;
    startViewAnimation(builder)
        .then((animation) => {
        builder.notifyReady(animation);
        return animation.finished;
    })
        // A genuinely failed transition (a throwing update) rejects the
        // builder; a skipped/interrupted one resolves with no animations (see
        // start.ts). Either way, advance the queue - else later transitions hang.
        .catch((error) => builder.notifyReject(error))
        .finally(next);
}
function processQueue() {
    /**
     * Iterate backwards over the builders array. We can ignore the
     * "wait" animations. If we have an interrupting animation in the
     * queue then we need to batch all preceeding animations into it.
     * Currently this only batches the update functions but will also
     * need to batch the targets.
     */
    for (let i = builders.length - 1; i >= 0; i--) {
        const builder = builders[i];
        const { interrupt } = builder.options;
        if (interrupt === "immediate") {
            const batchedUpdates = builders.slice(0, i + 1).map((b) => b.update);
            const remaining = builders.slice(i + 1);
            builder.update = () => {
                batchedUpdates.forEach((update) => update());
            };
            // Put the current builder at the front, followed by any "wait" builders
            builders = [builder, ...remaining];
            break;
        }
    }
    if (!current || builders[0]?.options.interrupt === "immediate") {
        next();
    }
}
function addToQueue(builder) {
    builders.push(builder);
    microtask.render(processQueue);
}

export { addToQueue };
//# sourceMappingURL=queue.mjs.map
