112 lines
2.7 KiB
TypeScript
112 lines
2.7 KiB
TypeScript
|
|
import { IndexedDBService, IQueueOperation } from './IndexedDBService';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Operation Queue Manager
|
||
|
|
* Handles FIFO queue of pending sync operations
|
||
|
|
*/
|
||
|
|
export class OperationQueue {
|
||
|
|
private indexedDB: IndexedDBService;
|
||
|
|
|
||
|
|
constructor(indexedDB: IndexedDBService) {
|
||
|
|
this.indexedDB = indexedDB;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Add operation to the end of the queue
|
||
|
|
*/
|
||
|
|
async enqueue(operation: Omit<IQueueOperation, 'id'>): Promise<void> {
|
||
|
|
await this.indexedDB.addToQueue(operation);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the first operation from the queue (without removing it)
|
||
|
|
* Returns null if queue is empty
|
||
|
|
*/
|
||
|
|
async peek(): Promise<IQueueOperation | null> {
|
||
|
|
const queue = await this.indexedDB.getQueue();
|
||
|
|
return queue.length > 0 ? queue[0] : null;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get all operations in the queue (sorted by timestamp FIFO)
|
||
|
|
*/
|
||
|
|
async getAll(): Promise<IQueueOperation[]> {
|
||
|
|
return await this.indexedDB.getQueue();
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Remove a specific operation from the queue
|
||
|
|
*/
|
||
|
|
async remove(operationId: string): Promise<void> {
|
||
|
|
await this.indexedDB.removeFromQueue(operationId);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Remove the first operation from the queue and return it
|
||
|
|
* Returns null if queue is empty
|
||
|
|
*/
|
||
|
|
async dequeue(): Promise<IQueueOperation | null> {
|
||
|
|
const operation = await this.peek();
|
||
|
|
if (operation) {
|
||
|
|
await this.remove(operation.id);
|
||
|
|
}
|
||
|
|
return operation;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Clear all operations from the queue
|
||
|
|
*/
|
||
|
|
async clear(): Promise<void> {
|
||
|
|
await this.indexedDB.clearQueue();
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the number of operations in the queue
|
||
|
|
*/
|
||
|
|
async size(): Promise<number> {
|
||
|
|
const queue = await this.getAll();
|
||
|
|
return queue.length;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Check if queue is empty
|
||
|
|
*/
|
||
|
|
async isEmpty(): Promise<boolean> {
|
||
|
|
const size = await this.size();
|
||
|
|
return size === 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get operations for a specific event ID
|
||
|
|
*/
|
||
|
|
async getOperationsForEvent(eventId: string): Promise<IQueueOperation[]> {
|
||
|
|
const queue = await this.getAll();
|
||
|
|
return queue.filter(op => op.eventId === eventId);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Remove all operations for a specific event ID
|
||
|
|
*/
|
||
|
|
async removeOperationsForEvent(eventId: string): Promise<void> {
|
||
|
|
const operations = await this.getOperationsForEvent(eventId);
|
||
|
|
for (const op of operations) {
|
||
|
|
await this.remove(op.id);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Update retry count for an operation
|
||
|
|
*/
|
||
|
|
async incrementRetryCount(operationId: string): Promise<void> {
|
||
|
|
const queue = await this.getAll();
|
||
|
|
const operation = queue.find(op => op.id === operationId);
|
||
|
|
|
||
|
|
if (operation) {
|
||
|
|
operation.retryCount++;
|
||
|
|
// Re-add to queue with updated retry count
|
||
|
|
await this.remove(operationId);
|
||
|
|
await this.enqueue(operation);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|