@alexanderfedin/async-queue
Version:
TypeScript async producer-consumer queue with backpressure control, similar to Go channels or .NET Channel<T>
205 lines • 6.13 kB
TypeScript
/**
* AsyncQueue - A TypeScript implementation of an async producer-consumer queue with backpressure control
* Uses circular buffer for O(1) enqueue/dequeue operations
*
* Developed by AI Hive® at O2.services
* https://o2.services
*
* Copyright (c) 2024 AI Hive® at O2.services
* Licensed under the MIT License
*/
/**
* AsyncQueue provides a thread-safe producer-consumer queue with backpressure control,
* similar to .NET's Channel<T> or Go channels.
* Uses a circular buffer for optimal performance.
*
* @template T The type of items in the queue
*/
export declare class AsyncQueue<T = any> {
private readonly maxSize;
private readonly buffer;
private head;
private tail;
private count;
private waitingConsumers;
private waitingConsumersCount;
private waitingProducers;
private waitingProducersCount;
private readonly INITIAL_WAITING_CAPACITY;
private closed;
/**
* Creates a new AsyncQueue instance
* @param maxSize Maximum number of items the queue can hold before producers block (default: 1)
*/
constructor(maxSize?: number);
/**
* Adds an item to the circular buffer
*/
private addToBuffer;
/**
* Removes an item from the circular buffer
*/
private removeFromBuffer;
/**
* Pushes a resolver onto a waiting queue with capacity management
*/
private pushWaiter;
/**
* Pops a resolver from a waiting queue (LIFO)
*/
private popWaiter;
/**
* Adds an item to the queue. Blocks if the queue is full.
* @param item The item to add to the queue
* @returns A promise that resolves when the item has been added
* @throws Error if the queue has been closed
*/
enqueue(item: T): Promise<void>;
/**
* Removes and returns the oldest item from the queue. Blocks if the queue is empty.
* @returns A promise that resolves to the item, or undefined if the queue is closed and empty
*/
dequeue(): Promise<T | undefined>;
/**
* Signals that no more items will be added to the queue.
* Existing items can still be consumed.
*/
close(): void;
/**
* Checks if the queue is closed AND empty
* @returns true if the queue is closed and has no remaining items
*/
get isClosed(): boolean;
/**
* Gets the current number of items in the queue
* @returns The number of items currently in the queue
*/
get size(): number;
/**
* Gets the maximum size of the queue
* @returns The maximum number of items the queue can hold
*/
get capacity(): number;
/**
* Checks if the queue is at full capacity
* @returns true if the queue is full
*/
get isFull(): boolean;
/**
* Checks if the queue is empty
* @returns true if the queue has no items
*/
get isEmpty(): boolean;
/**
* Gets the number of waiting consumers
* @returns The number of consumers waiting for items
*/
get waitingConsumerCount(): number;
/**
* Gets the number of waiting producers
* @returns The number of producers waiting for space
*/
get waitingProducerCount(): number;
/**
* Returns an async iterator for consuming items from the queue.
* Allows the queue to be used with for-await-of loops.
* The iterator will complete when the queue is closed and empty.
*
* @example
* ```typescript
* const queue = new AsyncQueue<number>();
*
* // Producer
* setTimeout(async () => {
* for (let i = 0; i < 5; i++) {
* await queue.enqueue(i);
* }
* queue.close();
* }, 0);
*
* // Consumer using async iterator
* for await (const item of queue) {
* console.log(item); // 0, 1, 2, 3, 4
* }
* ```
*/
[Symbol.asyncIterator](): AsyncIterator<T>;
/**
* Creates an async iterable that consumes items from the queue.
* This is an alternative way to get an async iterator.
*
* @returns An async iterable for consuming queue items
* @example
* ```typescript
* const queue = new AsyncQueue<string>();
* const iterator = queue.iterate();
*
* for await (const item of iterator) {
* console.log(item);
* }
* ```
*/
iterate(): AsyncIterable<T>;
/**
* Converts the queue to an async generator.
* Useful for transformation pipelines.
*
* @returns An async generator that yields items from the queue
* @example
* ```typescript
* const queue = new AsyncQueue<number>();
* const generator = queue.toAsyncGenerator();
*
* // Transform items
* async function* double(source: AsyncGenerator<number>) {
* for await (const item of source) {
* yield item * 2;
* }
* }
*
* for await (const item of double(generator)) {
* console.log(item);
* }
* ```
*/
toAsyncGenerator(): AsyncGenerator<T>;
/**
* Drains all items from the queue into an array.
* Waits until the queue is closed and returns all items.
*
* @returns A promise that resolves to an array of all items
* @example
* ```typescript
* const queue = new AsyncQueue<number>();
*
* // Producer
* (async () => {
* for (let i = 0; i < 5; i++) {
* await queue.enqueue(i);
* }
* queue.close();
* })();
*
* const items = await queue.drain();
* console.log(items); // [0, 1, 2, 3, 4]
* ```
*/
drain(): Promise<T[]>;
/**
* Takes up to n items from the queue.
* Returns early if the queue is closed before n items are received.
*
* @param n The maximum number of items to take
* @returns A promise that resolves to an array of items
* @example
* ```typescript
* const queue = new AsyncQueue<number>();
*
* // Take first 3 items
* const items = await queue.take(3);
* ```
*/
take(n: number): Promise<T[]>;
}
export default AsyncQueue;
//# sourceMappingURL=index.d.ts.map