export class ItemLoadError extends Error {
    code;
    constructor(code, message) {
        super(message);
        this.name = "ItemLoadError";
        this.code = code;
    }
}
function defaultItemEndpoint(itemVId, opts) {
    const url = new URL(`/api/item/${itemVId}`, "https://placeholder.invalid");
    if (opts?.organizationId)
        url.searchParams.set("organizationId", opts.organizationId);
    return url.pathname + url.search;
}
export function createFetchItemLoader(opts) {
    const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
    if (!fetchImpl) {
        throw new ItemLoadError("FETCH_NOT_AVAILABLE", "globalThis.fetch is not available in this environment");
    }
    return async (itemVId, loadOpts) => {
        const endpointBuilder = typeof opts.itemEndpoint === "function"
            ? opts.itemEndpoint
            : typeof opts.itemEndpoint === "string"
                ? () => opts.itemEndpoint
                : defaultItemEndpoint;
        const endpoint = endpointBuilder(itemVId, loadOpts);
        const url = new URL(endpoint, opts.baseUrl);
        const res = await fetchImpl(url.toString());
        if (!res.ok) {
            throw new ItemLoadError("FETCH_FAILED", `Failed to load item ${itemVId}: ${res.status} ${res.statusText}`);
        }
        return (await res.json());
    };
}
/**
 * Client-resolvable default loader:
 * - resolve from `itemBank` first (no backend required)
 * - optionally fallback to fetch (encouraged backend hook)
 */
export function createLoadItem(opts) {
    const itemBank = opts.itemBank;
    const fetchBaseUrl = opts.fetchBaseUrl;
    const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
    const fetchLoader = fetchBaseUrl && typeof fetchImpl === "function"
        ? createFetchItemLoader({
            baseUrl: fetchBaseUrl,
            itemEndpoint: opts.itemEndpoint,
            fetchImpl,
        })
        : null;
    return async (itemVId, loadOpts) => {
        if (itemBank?.[itemVId])
            return itemBank[itemVId];
        if (fetchLoader)
            return await fetchLoader(itemVId, loadOpts);
        if (fetchBaseUrl && typeof fetchImpl !== "function") {
            throw new ItemLoadError("FETCH_NOT_AVAILABLE", "fetchBaseUrl was provided but globalThis.fetch is not available");
        }
        throw new ItemLoadError("NO_ITEM_BANK_OR_FETCH_CONFIG", "No itemBank entry and no fetchBaseUrl configured for item loading");
    };
}
//# sourceMappingURL=item-loader.js.map