thorish
Version:
This is a library of useful JS concepts and data structures for Node and the browser. It it, unashamedly, a dumping ground for code needed by [@samthor](https://twitter.com/samthor)'s projects.
116 lines (115 loc) • 3.97 kB
TypeScript
export declare class WorkQueue<T> {
private pending;
private queue;
private releaseActive;
private releaseTask;
/**
* The {@link WorkQueue} releases waiting tasks one-per-microtask. This maintains the invariant
* that every time `wait` returns or resolves, there's at least one item in the queue: otherwise,
* resolving everything at once might allow other waiters to steal all items.
*/
private releasePending;
/**
* Iterates through the items in this queue _forever_, waiting for more items to appear.
*/
[Symbol.asyncIterator](): AsyncGenerator<T, void, void>;
asyncGenerator(): AsyncGenerator<T, void, void>;
/**
* Iterates through the items in this queue, stopping when no more are available synchronously.
*/
[Symbol.iterator](): Generator<NonNullable<T>, void, unknown>;
/**
* Waits until there is something in the queue that your task can process. This does _not_ return
* the item itself. This returns `undefined` if no waiting is required.
*/
wait(): void | Promise<void>;
/**
* Takes a token for the next item from the front of the queue. The returned {@link Promise} will
* always receive the next item, so don't throw it away.
*/
next(): Promise<T>;
/**
* Push items into the queue. Wakes up any pending requests.
*/
push(...items: T[]): number;
pop(): T | undefined;
/**
* Push items at the start of the queue. Wakes up any pending requests.
*/
unshift(...items: T[]): number;
shift(): T | undefined;
get length(): number;
}
/**
* Array-based queue. Faster thank {@link LinkQueue}, but cannot be garbage-collected.
*/
export interface Queue<X> {
/**
* Adds more events to the queue. Returns `true` if any listeners were directly woken up.
*/
push(...all: X[]): boolean;
/**
* Returns a listener that provides all events passed with `push` after this call completes.
*
* If the signal is cancelled, the listener becomes invalid and returns undefined values.
*/
join(signal: AbortSignal): Listener<X>;
}
/**
* Linked-list based queue.
*/
export interface LinkQueue<X> extends Queue<X> {
/**
* Returns a listener that provides all events passed with `push` after this call completes.
*
* If the signal is cancelled, the listener becomes invalid and returns undefined values.
*
* If the listener is garbage collected, it will lose the reference to the back of the queue.
*/
join(signal?: AbortSignal): Listener<X>;
}
/**
* Listener for a queue.
*/
export interface Listener<X> {
/**
* Determines if there's a pending queue event, returning it if available.
*
* Returns `undefined` if there is no event or the listener was aborted. It does not consume the
* event.
*/
peek(): X | undefined;
/**
* Waits for and returns the next queue event.
*
* Returns `undefined` if this listener was aborted.
*/
next(): Promise<X | undefined>;
/**
* Waits for and returns an array of all available queue events.
*
* If the array has zero length, the listener was aborted.
*/
batch(): Promise<X[]>;
/**
* Waits for and returns only the last pending event. This can be useful if the event is purely a
* "high water mark".
*/
last(): Promise<X | undefined>;
}
/**
* Builds an async generator over the given {@link Listener}.
*/
export declare function listenerToAsyncGenerator<X>(l: Listener<X>): AsyncGenerator<X, void, void>;
/**
* Builds a listener that never has any values in it, and resolves immediately. For aborted signals.
*/
export declare function buildEmptyListener<X = any>(): Listener<X>;
/**
* Builds a {@link LinkQueue}.
*/
export declare function buildLinkQueue<X>(): LinkQueue<X>;
/**
* Builds a {@link Queue}.
*/
export declare function buildArrayQueue<X>(): Queue<X>;