/// <reference path="./elkjs.d.ts" />
import { preprocessForElk } from "./workflow-preprocessor.js";
import { postprocessElkResult } from "./layout-postprocessor.js";
// ---------------------------------------------------------------------------
// Factory
// ---------------------------------------------------------------------------
/**
 * Creates an ELK-based layout engine with optional Web Worker support.
 *
 * This function dynamically imports elkjs — the import is deferred so that
 * the ~1.5MB WASM module is only loaded when layout is first requested,
 * not at SDK initialization time.
 *
 * If elkjs is not installed (optional peer dependency), the import will
 * reject and the caller should fall back to the dagre engine.
 *
 * @throws If elkjs cannot be imported (not installed or bundler misconfiguration).
 */
export async function createElkLayoutEngine(options) {
    const elk = await instantiateElk(options);
    return new ElkLayoutEngineImpl(elk, options?.layoutOptions);
}
async function instantiateElk(options) {
    if (options?.workerFactory) {
        try {
            const module = await import("elkjs/lib/elk-api.js");
            const ELK = module.default ?? module;
            return new ELK({ workerFactory: options.workerFactory });
        }
        catch {
            // Worker path failed — fall through to bundled
        }
    }
    const module = await import("elkjs/lib/elk.bundled.js");
    const ELK = module.default ?? module;
    return new ELK();
}
// ---------------------------------------------------------------------------
// Engine Implementation
// ---------------------------------------------------------------------------
class ElkLayoutEngineImpl {
    name = "elk-layered";
    elk;
    optionOverrides;
    terminated = false;
    constructor(elk, optionOverrides) {
        this.elk = elk;
        this.optionOverrides = optionOverrides;
    }
    async layout(input) {
        if (this.terminated) {
            throw new Error("ELK layout engine has been terminated.");
        }
        const start = performance.now();
        const elkGraph = preprocessForElk(input, this.optionOverrides);
        const rawResult = await this.elk.layout(elkGraph);
        const elkResult = rawResult;
        const durationMs = performance.now() - start;
        return postprocessElkResult(elkResult, input.scope, input.graph, durationMs, this.name);
    }
    terminate() {
        this.terminated = true;
        if ("terminateWorker" in this.elk && typeof this.elk.terminateWorker === "function") {
            this.elk.terminateWorker();
        }
    }
}
//# sourceMappingURL=elk-layout-engine.js.map