import { on, dispatchEvent } from "../schedule/index.js";
import { isLike, ok } from "../../is.js";
import { getServiceWorkerModuleExports } from "../../worker/service-worker/worker-exports.js";
const DISPATCH = "dispatch";
export function isDispatchEvent(event) {
    return !!(isLike(event) &&
        event.type === "dispatch" &&
        event.dispatch);
}
export async function onDispatchEvent(event) {
    if (!isDispatchEvent(event))
        return;
    if (Array.isArray(event.dispatch)) {
        // Allows parallel dispatch with one main event
        // If serial dispatches are wanted this can be done with just multiple
        // immediate dispatches using `dispatchEvent` directly
        //
        // Parallel dispatch is useful in a service worker with many fetch events
        // at once, say for `.addAll(urls)`
        await Promise.all(event.dispatch.map(dispatch => ({
            ...event,
            dispatch
        })));
        return;
    }
    if (event.dispatch.type === "dispatch") {
        // This is to prevent infinite loops
        console.warn("dispatch cannot be used to dispatch additional events");
        return;
    }
    let dispatching = {
        ...event.dispatch
    };
    const entrypointArguments = event.entrypointArguments;
    async function dispatchEntrypointEvent(entrypoint) {
        ok(typeof entrypoint === "function", "Expected entrypoint to be a function");
        if (entrypointArguments) {
            const dispatchArguments = entrypointArguments.map(key => key === "$event" ? dispatching : dispatching[key]);
            return entrypoint(...dispatchArguments);
        }
        else {
            ok(entrypoint);
            return entrypoint(dispatching);
        }
    }
    if (event.entrypoint) {
        const entrypoints = getServiceWorkerModuleExports();
        if (typeof entrypoints[event.entrypoint] === "function") {
            await dispatchEntrypointEvent(entrypoints[event.entrypoint]);
        }
        else if (isLike(entrypoints) && entrypoints.default && typeof entrypoints.default[event.entrypoint] === "function") {
            await dispatchEntrypointEvent(entrypoints.default[event.entrypoint]);
        }
        else {
            throw new Error(`Unknown entrypoint ${event.entrypoint}`);
        }
    }
    else {
        if (!dispatching.durableEventId) {
            dispatching.virtual = true;
        }
        if (!dispatching.virtual && !dispatching.schedule) {
            dispatching.schedule = {
                immediate: true
            };
        }
        await dispatchEvent(dispatching);
    }
}
export const removeDispatchScheduledFunction = on(DISPATCH, onDispatchEvent);
//# sourceMappingURL=index.js.map