export const LOADING_INDICATOR_MS = 150;
export function createDetailJobs(emit) {
    let token = 0;
    let current = null;
    const abortedTokens = new Set();
    return {
        async schedule(rowId, items, ctx) {
            if (current !== null) {
                current.controller.abort();
                clearTimeout(current.loadingTimer);
            }
            const nextToken = ++token;
            const controller = new AbortController();
            let finished = false;
            const loadingTimer = setTimeout(() => {
                if (!finished && !abortedTokens.has(nextToken)) {
                    emit({ type: "detailLoading", rowId, token: nextToken });
                }
            }, LOADING_INDICATOR_MS);
            current = { controller, loadingTimer, token: nextToken };
            try {
                const loadedItems = await items({ ...ctx, signal: controller.signal });
                finished = true;
                if (!abortedTokens.has(nextToken)) {
                    emit({ type: "detailLoaded", rowId, token: nextToken, items: loadedItems });
                }
            }
            catch (error) {
                finished = true;
                if (!abortedTokens.has(nextToken)) {
                    emit({ type: "detailError", rowId, token: nextToken, error: toError(error) });
                }
            }
            finally {
                finished = true;
                clearTimeout(loadingTimer);
                abortedTokens.delete(nextToken);
                if (current?.controller === controller) {
                    current = null;
                }
            }
        },
        abort() {
            if (current === null) {
                return;
            }
            current.controller.abort();
            clearTimeout(current.loadingTimer);
            abortedTokens.add(current.token);
            current = null;
        }
    };
}
function toError(error) {
    if (error instanceof Error) {
        return error;
    }
    return new Error(String(error));
}
