This commit is contained in:
Oscar
2026-06-03 20:21:43 +03:00
commit a38e905b29
25 changed files with 19011 additions and 0 deletions

View File

@@ -0,0 +1,65 @@
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', ids: number[] }
type Task = AddTask | SelectTask | DeselectTask | ReorderTask
class RequestQueue {
private addQueue: AddTask[] = []
private actionQueue: ReorderTask[] = []
private pendingKeys = new Set<string>()
private pendingReorder: ReorderTask | null = null
constructor() {
setInterval(() => this.flushAdd(), 10_000)
setInterval(() => this.flushActions(), 1_000)
}
enqueue(task: Task): boolean {
if (task.type === 'reorder') {
this.pendingReorder = task
this.actionQueue = this.actionQueue.filter(t => t.type !== 'reorder')
this.actionQueue.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 flushActions(): void {
const batch = this.actionQueue.splice(0)
this.pendingReorder = null
for (const task of batch) {
if (task.type === 'reorder') {
store.reorderSelected(task.ids)
}
}
}
}
export const queue = new RequestQueue()