import * as store from './itemsStore.js' interface AddTask { type: 'add', id: number } interface SelectTask { type: 'select', id: number } interface DeselectTask { type: 'deselect', id: number } interface ReorderTask { type: 'reorder', id: number, afterId: number | null } type Task = AddTask | SelectTask | DeselectTask | ReorderTask class RequestQueue { private addQueue: AddTask[] = [] private reorderQueue: ReorderTask[] = [] private pendingKeys = new Set() constructor() { setInterval(() => this.flushAdd(), 10_000) setInterval(() => this.flushReorder(), 1_000) } enqueue(task: Task): boolean { if (task.type === 'reorder') { this.reorderQueue.push(task) return true } const key = `${task.type}:${(task as AddTask | SelectTask | DeselectTask).id}` if (this.pendingKeys.has(key)) return false this.pendingKeys.add(key) if (task.type === 'add') { this.addQueue.push(task) if (this.addQueue.length >= 100) this.flushAdd() } else { // select/deselect применяются немедленно, чтобы GET после POST видел актуальный state if (task.type === 'select') store.selectItem(task.id) else if (task.type === 'deselect') store.deselectItem(task.id) this.pendingKeys.delete(key) } return true } private flushAdd(): void { const batch = this.addQueue.splice(0) for (const task of batch) { store.addItem(task.id) this.pendingKeys.delete(`add:${task.id}`) } } private flushReorder(): void { const batch = this.reorderQueue.splice(0) for (const task of batch) { store.reorderItem(task.id, task.afterId) } } } export const queue = new RequestQueue()