UNPKG

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
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>;