@thi.ng/csp
Version:
Primitives & operators for Communicating Sequential Processes based on async/await and async iterables
164 lines • 6.26 kB
TypeScript
import type { Fn, Maybe } from "@thi.ng/api";
import type { ChannelBuffer, ChannelValue, IChannel } from "./api.js";
export declare const MAX_READS = 1024;
export declare const MAX_WRITES = 1024;
export interface ChannelOpts {
id: string;
}
/**
* Syntax sugar for creating a new CSP {@link Channel}. By default, the channel
* has a buffer capacity of 1 value, but supports custom buffer sizes and/or
* implementations (described in readme).
*
* @param opts
*/
export declare function channel<T>(opts?: Partial<ChannelOpts>): Channel<T>;
export declare function channel<T>(buf: ChannelBuffer<T> | number, opts?: Partial<ChannelOpts>): Channel<T>;
export declare class Channel<T> implements IChannel<T> {
id: string;
writes: ChannelBuffer<T>;
queue: ChannelValue<T>[];
reads: Fn<Maybe<T>, void>[];
races: Fn<Channel<T>, void>[];
protected state: number;
/**
* See {@link channel} for reference.
*
* @param opts
*/
constructor(opts?: Partial<ChannelOpts>);
constructor(buf: ChannelBuffer<T> | number, opts?: Partial<ChannelOpts>);
/**
* Returns an async iterator of this channel, acting as adapter between the
* CSP world and the more generic ES async iterables. The iterator stops
* once the channel has been closed and no further values can be read.
*
* @remarks
* Multiple iterators will compete for new values. To ensure an iterator
* receives all of the channel's values, you must either ensure there's only
* a single iterator per channel or feed the channel into a {@link mult}
* first and create an iterator of a channel obtained via
* {@link Mult.subscribe}.
*
* @example
* ```ts tangle:../export/channel-iterator.ts
* import { channel } from "@thi.ng/csp";
*
* const chan = channel<number>();
*
* (async () => {
* // implicit iterator conversion of the channel
* for await(let x of chan) console.log("received", x);
* console.log("channel closed");
* })()
*
* chan.write(1);
* chan.write(2);
* chan.write(3);
* chan.close();
* ```
*/
[Symbol.asyncIterator](): AsyncIterableIterator<T>;
/**
* Attempts to read a value from the channel. The returned promise will
* block until such value becomes available or if the channel has been
* closed in the meantime. In that latter case, the promise will resolve to
* `undefined`.
*
* @remarks
* If a value is already available at the time of the function call, the
* promise resolves immediately.
*
* Note: There's a limit of in-flight {@link MAX_READS} allowed per channel.
* The promise will reject if that number is exceeded.
*
* Also see {@link Channel.poll}.
*/
read(): Promise<Maybe<T>>;
/**
* Similar to {@link Channel.read}, but not async and non-blocking. Will
* only succeed if the channel is readable (i.e. not yet closed) and if a
* value can be read immediately (without waiting). Returns the value or
* `undefined` if unsuccessful.
*
* @remarks
* Use {@link Channel.closed} to check if the channel is already closed.
*/
poll(): Maybe<T>;
/**
* Attempts to write a new value to the channel and returns a promise
* indicating success or failure. Depending on buffer capacity & behavior,
* the returned promise will block until the channel accept new values (i.e.
* until the next {@link Channel.read}) or if it has been closed in the
* meantime. In that latter case, the promise will resolve to false.
*
* @remarks
* If the channel's buffer accepts new writes or if a read op is already
* waiting at the time of the function call, the promise resolves
* immediately.
*
* If the buffer is already full, the write will be queued and only resolve
* when delivered. Note: As a fail-safe, there's a limit of queued
* {@link MAX_WRITES} allowed per channel. The promise will reject if that
* number is exceeded.
*
* Also see {@link Channel.offer}.
*/
write(msg: T): Promise<boolean>;
/**
* Similar to {@link Channel.write}, but not async and non-blocking. Will
* only succeed if the channel is writable (i.e. not yet closed/closing) and
* if a write is immediately possible (without queuing). Returns true, if
* successful.
*
* @param msg
*/
offer(msg: T): boolean;
/**
* Queues a "race" operation & returns a promise which resolves with the
* channel itself when the channel becomes readable, but no other queued
* read operations are waiting (which always have priority). If the channel
* is already closed, the promise resolves immediately.
*
* @remarks
* This op is used internally by {@link select} to choose a channel to read
* from next.
*/
race(): Promise<Channel<T>>;
/**
* Triggers closing of the channel (idempotent). Any queued writes remain
* readable, but new writes will be ignored.
*
* @remarks
* Whilst there're still values available for reading,
* {@link Channel.closed} will still return false since the channel state is
* still "closing", not yet fully "closed".
*/
close(): void;
/**
* Returns true if the channel is principally readable (i.e. not yet
* closed), however there might not be any values available yet and reads
* might block.
*/
readable(): boolean;
/**
* Returns true if the channel is principally writable (i.e. not closing or
* closed), however depending on buffer behavior the channel might not yet
* accept new values and writes might block.
*/
writable(): boolean;
/**
* Returns true if the channel is fully closed and no further reads or
* writes are possible.
*
* @remarks
* Whilst there're still values available for reading, this will still
* return false since the channel state is still "closing", not yet fully
* "closed".
*/
closed(): boolean;
/** @internal */
updateQueue(): void;
protected deliver(): void;
}
//# sourceMappingURL=channel.d.ts.map