import { OperationQueue } from "../util/operation-queue.js";
export class OperationProcessor {
    config;
    operationQueue;
    pendingOperations = [];
    batchTimer = null;
    _enabled = true;
    constructor(config = {}) {
        this.config = {
            batchWindowMs: 50,
            maxBatchSize: 100,
            ...config,
        };
        this.operationQueue = new OperationQueue();
    }
    async addOperation(operation) {
        const timestamp = Date.now();
        const id = `operation-${timestamp}-${Math.random()}`;
        const fullOperation = {
            ...operation,
            id,
            timestamp,
        };
        if (!this._enabled || fullOperation.priority) {
            return this.processOperations([fullOperation]);
        }
        this.pendingOperations.push(fullOperation);
        if (this.pendingOperations.length >= this.config.maxBatchSize) {
            return this.flush();
        }
        this.resetBatchTimer();
    }
    async flush() {
        if (this.pendingOperations.length === 0) {
            return;
        }
        const operations = [...this.pendingOperations];
        this.pendingOperations = [];
        this.clearBatchTimer();
        return this.operationQueue.enqueue(() => this.processOperations(operations));
    }
    disable() {
        this.setEnabled(false);
    }
    enable() {
        this.setEnabled(true);
    }
    setEnabled(enabled) {
        const wasEnabled = this._enabled;
        this._enabled = enabled;
        if (!enabled && wasEnabled && this.pendingOperations.length > 0) {
            this.flush().catch((error) => {
                console.error("Error flushing operations on priority mode enable:", error);
            });
        }
    }
    async processOperations(operations) {
        if (operations.length === 0) {
            return;
        }
        for (const operation of operations) {
            await operation.execute();
        }
    }
    resetBatchTimer() {
        this.clearBatchTimer();
        this.batchTimer = setTimeout(() => {
            this.flush().catch((error) => {
                console.error("Error flushing operations on timer:", error);
            });
        }, this.config.batchWindowMs);
    }
    clearBatchTimer() {
        if (this.batchTimer) {
            clearTimeout(this.batchTimer);
            this.batchTimer = null;
        }
    }
}
//# sourceMappingURL=operation-processor.js.map