import type { BaseSelectorKey, DataFetcher, DataHandler, AsyncDataFetcher, DuplexTransfer, First, Last, InputTransfer, OutputTransfer, SelectorKey, CompositeTransfer, OutputTransferDataType, InputTransferDataType, ErrorHandler, CompositeDuplexTransfer, CompositeInputTransfer, CompositeOutputTransfer, } from "./types"; import { LinkConfig } from "./configs"; /** * Write-only flow — accepts data via write(). * @category Interfaces */ export interface InputFlowInterface { write(data: T): void; } /** * Read-only flow — yields data via read(). * @category Interfaces */ export interface OutputFlowInterface { read(): T | undefined; } /** * Bidirectional flow — combines read and write. * @category Interfaces */ export interface IOFlowInterface extends InputFlowInterface, OutputFlowInterface {} /** * Bidirectional storage with size tracking, clear, and reset. * @category Interfaces */ export interface StorageInterface extends IOFlowInterface { readonly size: number; clear(): void; reset(): void; } /** * Asynchronous write-only flow — accepts data via async write(). * @category Interfaces */ export interface AsyncInputFlowInterface { write(data: T): Promise; } /** * Asynchronous read-only flow — yields data via async read(). * @category Interfaces */ export interface AsyncOutputFlowInterface { read(): Promise; } /** * Asynchronous bidirectional flow — combines async read and write. * @category Interfaces */ export interface AsyncIOFlowInterface extends AsyncInputFlowInterface, AsyncOutputFlowInterface {} /** * Asynchronous bidirectional storage with async clear/reset. * @category Interfaces */ export interface AsyncStorageInterface extends AsyncIOFlowInterface { readonly size: number; clear(): Promise; reset(): Promise; } /** * Synchronous data transformation operator — maps TInput to TOutput. * @category Interfaces */ export interface OperatorInterface { apply(data: TInput): TOutput; } /** * Asynchronous data transformation operator — maps TInput to Promise. * @category Interfaces */ export interface AsyncOperatorInterface { apply(data: TInput): Promise; } /** * Ticker interface — an abstraction over periodic callback invocation. * Two implementations: RAFTicker (browser, requestAnimationFrame) and IntervalTicker (Node.js, setInterval). * * @category Interfaces */ export interface TickerInterface { /** Interval in milliseconds */ readonly interval: number; /** Whether the ticker is active (running) */ readonly active: boolean; /** Start the ticker (with a leading-edge call) */ start(): void; /** Stop the ticker */ stop(): void; /** Stop and restart */ restart(): void; /** Toggle state (start/stop), returns the new state */ toggle(): boolean; /** Update interval on the fly (restarts the ticker if active) */ updateInterval(delay: number): void; } /** * Subscription handle — tracks active state and supports unsubscribe lifecycle hooks. * @category Interfaces */ export interface SubscriberInterface { readonly active: boolean; unsubscribe(): void; onUnsubscribe(handler: DataHandler): SubscriberInterface; offUnsubscribe(handler: DataHandler): SubscriberInterface; } /** * Resource cleanup contract — destroy() releases all held resources. * @category Interfaces */ export interface DisposableInterface { destroy(): void; } /** * Flow control contract — activate/deactivate/toggle with state-change subscriptions. * @category Interfaces */ export interface GateInterface { readonly active: boolean; activate(): void; deactivate(): void; toggle(): boolean; onStateChange(handler: DataHandler): SubscriberInterface; } /** * Pushable contract — accepts data via push(). * @category Interfaces */ export interface PushableInterface { push(data: T): void; } /** * Pullable contract — yields data via pull(). * @category Interfaces */ export interface PullableInterface { pull(): T | undefined; } /** * Subscribable contract — registers a handler that is called on each emitted value. * @category Interfaces */ export interface SubscribableInterface { subscribe(handler: DataHandler): SubscriberInterface; } /** * Triggerable contract — manually triggers emission of the current value to subscribers. * @category Interfaces */ export interface TriggerableInterface { trigger(): void; } /** * Polling proxy contract — receives a fetcher from the upstream transfer and manages its lifecycle via set/clear. * @category Interfaces */ export interface PollingProxyInterface { setFetcher(fetcher: DataFetcher): void; clearFetcher(): void; } /** * Asynchronous pushable contract — accepts data via asyncPush() returning a Promise. * @category Interfaces */ export interface AsyncPushableInterface { asyncPush(data: T): Promise; } /** * Asynchronous pullable contract — yields data via asyncPull() returning a Promise. * @category Interfaces */ export interface AsyncPullableInterface { asyncPull(): Promise; } /** * Asynchronous triggerable contract — triggers emission via asyncTrigger() returning a Promise. * @category Interfaces */ export interface AsyncTriggerableInterface { asyncTrigger(): Promise; } /** * Async polling proxy contract — receives an async fetcher from the upstream transfer and manages its lifecycle. * @category Interfaces */ export interface AsyncPollingProxyInterface { setAsyncFetcher(fetcher: AsyncDataFetcher): void; clearAsyncFetcher(): void; } /** * Universal input interface — aggregates all sync and async input capabilities (push, poll, trigger, gate, async variants). * @category Interfaces */ export interface UniversalInputInterface extends BaseTransferInterface, PushableInterface, PollingProxyInterface, TriggerableInterface, GateInterface, AsyncPushableInterface, AsyncPollingProxyInterface, AsyncTriggerableInterface {} /** * Universal output interface — aggregates all sync and async output capabilities (pull, subscribe, trigger, gate, async variants). * @category Interfaces */ export interface UniversalOutputInterface extends BaseTransferInterface, PullableInterface, SubscribableInterface, TriggerableInterface, GateInterface, AsyncPullableInterface, AsyncTriggerableInterface {} /** * Universal duplex interface — combines all input and output capabilities. * @category Interfaces */ export interface UniversalDuplexInterface extends UniversalInputInterface, UniversalOutputInterface {} /** * Contract of capability flags — boolean properties that determine which interfaces and methods a transfer supports. * @category Interfaces */ export interface CommunicationContractInterface { // Direction and nature of the flow readonly isInput: boolean; // can act as an input readonly isOutput: boolean; // can act as an output readonly isDuplex: boolean; // can be both input and output simultaneously // Data delivery mechanics readonly isPollingSource: boolean; // can periodically poll some source readonly isPollingProxy: boolean; // can periodically poll some source readonly isPushable: boolean; // data can be pushed into it readonly isPullable: boolean; // data can be pulled from it readonly isSubscribable: boolean; // can be subscribed to readonly isTriggerable: boolean; // can be triggered manually readonly isGate: boolean; // can be activated/deactivated // Asynchronous data delivery mechanics readonly isAsyncPushable: boolean; // data can be pushed into it asynchronously readonly isAsyncPullable: boolean; // data can be pulled from it asynchronously readonly isAsyncTriggerable: boolean; // can be triggered asynchronously readonly isAsyncPollingProxy: boolean; // can asynchronously poll another transfer } /** * Base transfer interface — combines capability flags with disposable lifecycle. * @category Interfaces */ export interface BaseTransferInterface extends CommunicationContractInterface, DisposableInterface {} /** * Transfer with gate-controlled push/subscribe — data flows only when the gate is active. * @category Interfaces */ export interface GateTransferInterface extends GateInterface, PushableTransferInterface, SubscribableTransferInterface { readonly isInput: true; readonly isOutput: true; readonly isPushable: true; readonly isSubscribable: true; readonly isGate: true; } /** * Pushable transfer — input transfer that supports synchronous data push via push(). * @category Interfaces */ export interface PushableTransferInterface extends PushableInterface, BaseTransferInterface { readonly isInput: true; readonly isPushable: true; } /** * Polling source transfer — fetcher is passed via config at construction time. Output-only (cannot be an input). * @category Interfaces */ export interface PollingSourceTransferInterface extends BaseTransferInterface, GateInterface { readonly isOutput: true; readonly isPollingSource: true; readonly isGate: true; } /** * Polling proxy transfer — fetcher is connected from the upstream transfer in the chain. At least an input. * @category Interfaces */ export interface PollingProxyTransferInterface extends PollingProxyInterface, BaseTransferInterface, GateInterface { readonly isInput: true; readonly isPollingProxy: true; } /** * Pullable transfer — output transfer that supports synchronous data extraction via pull(). * @category Interfaces */ export interface PullableTransferInterface extends PullableInterface, BaseTransferInterface { readonly isOutput: true; readonly isPullable: true; } /** * Subscribable transfer — output transfer that supports reactive subscription via subscribe(). * @category Interfaces */ export interface SubscribableTransferInterface extends SubscribableInterface, BaseTransferInterface { readonly isOutput: true; readonly isSubscribable: true; } /** * Triggerable transfer — transfer that supports manual emission via trigger(). * @category Interfaces */ export interface TriggerableTransferInterface extends TriggerableInterface, BaseTransferInterface { readonly isTriggerable: true; } /** * Async pushable transfer — input transfer that supports asynchronous data push via asyncPush(). * @category Interfaces */ export interface AsyncPushableTransferInterface extends AsyncPushableInterface, BaseTransferInterface { readonly isInput: true; readonly isAsyncPushable: true; } /** * Async pullable transfer — output transfer that supports asynchronous data extraction via asyncPull(). * @category Interfaces */ export interface AsyncPullableTransferInterface extends AsyncPullableInterface, BaseTransferInterface { readonly isOutput: true; readonly isAsyncPullable: true; } /** * Async polling proxy transfer — input transfer that supports async polling of an upstream transfer via setAsyncFetcher/clearAsyncFetcher. * @category Interfaces */ export interface AsyncPollingProxyTransferInterface extends AsyncPollingProxyInterface, BaseTransferInterface, GateInterface { readonly isInput: true; readonly isAsyncPollingProxy: true; } /** * Operator pipeline builder interface — type-safe chaining of operators * with tuple-based type inference. Each add() appends the output type to TFlow. * * @category Interfaces */ export interface OperatorPipelineBuilderInterface { /** * Overload for an empty builder: accepts the first operator * and initializes the TFlow tuple with types [TInput, TOutput]. */ add( this: OperatorPipelineBuilderInterface<[]>, operator: OperatorInterface ): OperatorPipelineBuilderInterface<[TInput, TOutput]>; /** * Overload for a builder that already has operators: * strictly requires that the input of the new operator matches the output of the previous one (Last). */ add( this: OperatorPipelineBuilderInterface, operator: OperatorInterface, TNext> ): OperatorPipelineBuilderInterface<[...TFlow, TNext]>; /** * Builds the final standalone PipelineOperator. * This method is only available if at least one operator has been added to the builder. */ build( this: OperatorPipelineBuilderInterface ): OperatorInterface, Last>; } /** * Async operator pipeline builder interface — like OperatorPipelineBuilderInterface, * but accepts both sync and async operators. Async overloads are listed first to avoid * TOutput being inferred as Promise. * * @category Interfaces */ export interface AsyncOperatorPipelineBuilderInterface { // Async overload first: AsyncMapOperator is structurally // compatible with both AsyncOperatorInterface and // OperatorInterface> — a union would infer // TOutput = Promise. Separate overloads with async first // force TypeScript to select the correct TOutput = TOut. add( this: AsyncOperatorPipelineBuilderInterface<[]>, operator: AsyncOperatorInterface ): AsyncOperatorPipelineBuilderInterface<[TInput, TOutput]>; add( this: AsyncOperatorPipelineBuilderInterface<[]>, operator: OperatorInterface ): AsyncOperatorPipelineBuilderInterface<[TInput, TOutput]>; add( this: AsyncOperatorPipelineBuilderInterface, operator: AsyncOperatorInterface, TNext> ): AsyncOperatorPipelineBuilderInterface<[...TFlow, TNext]>; add( this: AsyncOperatorPipelineBuilderInterface, operator: OperatorInterface, TNext> ): AsyncOperatorPipelineBuilderInterface<[...TFlow, TNext]>; build( this: AsyncOperatorPipelineBuilderInterface ): AsyncOperatorInterface, Last>; } /** * Unified composite transfer builder interface — replaces Input/Output/Duplex builder interfaces. * * Pipeline structure: OutputTransfer [→ DuplexTransfer → …] → InputTransfer. * The start transfer provides output capabilities (source of data); * intermediate transfers are duplex (relay data through the chain); * the finish transfer provides input capabilities (sink for data). * * The composite result exposes: * - Input flags (Pushable, PollingProxy, AsyncPushable, AsyncPollingProxy) from the start transfer. * - Output flags (Pullable, Subscribable, AsyncPullable) from the finish transfer. * - Triggerable, AsyncTriggerable, Gate from explicit options or extracted by UniversalCompositeTransfer. * * Works for both sync and async pipelines — `onLinkError` in finish() options enables async error handling. * * @category Interfaces */ export interface CompositeTransferBuilderInterface< TCurrent, TStartTransfer extends OutputTransfer, > { to>( nextTransfer: TNextTransfer, options?: { owned?: boolean; onLinkError?: ErrorHandler; }, ): CompositeTransferBuilderInterface, TStartTransfer>; finish< TFinishTransfer extends InputTransfer, TTriggerable extends TriggerableInterface | undefined = undefined, TAsyncTriggerable extends AsyncTriggerableInterface | undefined = undefined, TGate extends GateInterface | undefined = undefined, >( lastTransfer: TFinishTransfer, options?: { triggerable?: TTriggerable; asyncTriggerable?: TAsyncTriggerable; gate?: TGate; owned?: boolean; onLinkError?: ErrorHandler; }, ): CompositeTransfer< InputTransferDataType, OutputTransferDataType, TStartTransfer, TFinishTransfer, TTriggerable, TAsyncTriggerable, TGate >; } /** * Bridge contract — a gated, disposable connection between two transfers. * * @category Interfaces */ export interface BridgeInterface extends GateInterface, DisposableInterface {} /** * Selector bridge interface — single-active-bridge selection from a keyed map. * * @category Interfaces */ export interface BridgeSelectorInterface> extends BridgeInterface { readonly selectedKey: SelectorKey; readonly selectedBridge: BridgeInterface; select(key: SelectorKey): void; } /** * Multi-selector bridge interface — multi-active-bridge selection with check/uncheck granularity. * * @category Interfaces */ export interface BridgeMultiSelectorInterface> extends BridgeInterface { readonly selectedKeys: SelectorKey[]; readonly selectedBridges: BridgeInterface[]; select(keys: SelectorKey[]): void; check(key: SelectorKey): void; uncheck(key: SelectorKey): void; } /** * Strategy interface for linking transfers. * * A link strategy provides a single method: * - `link()` — connects an output transfer to an input transfer based on their capability flags * * Implementations can override the method to customize linking behavior * (e.g., logging, serialization, custom error handling for unsupported combinations). * * @example * ```typescript * const linkStrategy = new DefaultLinkStrategy(); * linkStrategy.link(source, target); * ``` * * @category Interfaces */ export interface LinkStrategyInterface { /** * Links an output transfer (LHS) to an input transfer (RHS). * * The linking strategy is determined by the capability flags of both transfers. * Sync strategies take priority over async ones. * * @typeParam T — data type flowing through the link * @typeParam RTransfer — type of the input transfer (RHS) * @param lhs — output transfer (source) * @param rhs — input transfer (sink) * @param options — optional link config (onError for async-push rejection) * @returns SubscriberInterface for breaking the link */ link>( lhs: OutputTransfer, rhs: RTransfer, options?: LinkConfig, ): SubscriberInterface; } // ═══════════════════════════════════════════════════════════════ // Deprecated interfaces // ═══════════════════════════════════════════════════════════════ /** * @deprecated Use `CompositeTransferBuilderInterface` instead. Will be removed in the next major release. * * Input pipeline builder interface — produces a strictly input-only composite transfer. * * Pipeline structure: TStartTransfer [→ DuplexTransfer → …] → InputTransfer. * The start transfer must be duplex; the finish transfer is input-only (no output methods exposed). * * @category Interfaces */ export interface InputPipelineBuilderInterface> { to( nextTransfer: DuplexTransfer, owned?: boolean, ): InputPipelineBuilderInterface; finish< TTriggerable extends TriggerableInterface | undefined = undefined, TGate extends GateInterface | undefined = undefined, >( lastTransfer: InputTransfer, options?: { triggerable?: TTriggerable, gate?: TGate, owned?: boolean, }, ): CompositeInputTransfer, TStartTransfer, TTriggerable, undefined, TGate>; } /** * @deprecated Use `CompositeTransferBuilderInterface` instead. Will be removed in the next major release. * * Output pipeline builder interface — produces a duplex composite transfer with output-only start. * * Pipeline structure: OutputTransfer [→ DuplexTransfer → …] → TFinishTransfer. * The start transfer must be output-only; the finish transfer is duplex. Input methods are not exposed. * * @category Interfaces */ export interface OutputPipelineBuilderInterface { to( nextTransfer: DuplexTransfer, owned?: boolean, ): OutputPipelineBuilderInterface; finish< TFinishTransfer extends DuplexTransfer, TTriggerable extends TriggerableInterface | undefined = undefined, TGate extends GateInterface | undefined = undefined, >( lastTransfer: TFinishTransfer, options?: { triggerable?: TTriggerable; gate?: TGate; owned?: boolean; }, ): CompositeOutputTransfer, TFinishTransfer, TTriggerable, undefined, TGate>; } /** * @deprecated Use `CompositeTransferBuilderInterface` instead. Will be removed in the next major release. * * Duplex pipeline builder interface — produces a duplex composite transfer. * * Pipeline structure: TStartTransfer [→ DuplexTransfer → …] → TFinishTransfer. * Both start and finish transfers are duplex; both input and output methods are exposed. * * @category Interfaces */ export interface DuplexPipelineBuilderInterface< TCurrent, TStartTransfer extends InputTransfer, > { to( nextTransfer: DuplexTransfer, owned?: boolean, ): DuplexPipelineBuilderInterface; finish< TFinishTransfer extends DuplexTransfer, TTriggerable extends TriggerableInterface | undefined = undefined, TGate extends GateInterface | undefined = undefined, >( lastTransfer: TFinishTransfer, options?: { triggerable?: TTriggerable; gate?: TGate; owned?: boolean; }, ): CompositeDuplexTransfer< InputTransferDataType, OutputTransferDataType, TStartTransfer, TFinishTransfer, TTriggerable, undefined, TGate >; } /** * @deprecated Use `CompositeTransferBuilderInterface` instead. Will be removed in the next major release. * * Async input pipeline builder interface — like InputPipelineBuilderInterface, * but supports async triggerable and linkOnError for async-push rejection handling. * * @category Interfaces */ export interface AsyncInputPipelineBuilderInterface> { to( nextTransfer: DuplexTransfer, owned?: boolean, ): AsyncInputPipelineBuilderInterface; finish< TTriggerable extends TriggerableInterface | undefined = undefined, TAsyncTriggerable extends AsyncTriggerableInterface | undefined = undefined, TGate extends GateInterface | undefined = undefined, >( lastTransfer: InputTransfer, options?: { triggerable?: TTriggerable; asyncTriggerable?: TAsyncTriggerable; gate?: TGate; owned?: boolean; linkOnError?: ErrorHandler>; }, ): CompositeInputTransfer, TStartTransfer, TTriggerable, TAsyncTriggerable, TGate>; } /** * @deprecated Use `CompositeTransferBuilderInterface` instead. Will be removed in the next major release. * * Async output pipeline builder interface — like OutputPipelineBuilderInterface, * but supports async triggerable and linkOnError for async-push rejection handling. * * @category Interfaces */ export interface AsyncOutputPipelineBuilderInterface { to( nextTransfer: DuplexTransfer, owned?: boolean, ): AsyncOutputPipelineBuilderInterface; finish< TFinishTransfer extends DuplexTransfer, TTriggerable extends TriggerableInterface | undefined = undefined, TAsyncTriggerable extends AsyncTriggerableInterface | undefined = undefined, TGate extends GateInterface | undefined = undefined, >( lastTransfer: TFinishTransfer, options?: { triggerable?: TTriggerable; asyncTriggerable?: TAsyncTriggerable; gate?: TGate; owned?: boolean; linkOnError?: ErrorHandler; }, ): CompositeOutputTransfer, TFinishTransfer, TTriggerable, TAsyncTriggerable, TGate>; } /** * @deprecated Use `CompositeTransferBuilderInterface` instead. Will be removed in the next major release. * * Async duplex pipeline builder interface — like DuplexPipelineBuilderInterface, * but supports async triggerable and linkOnError for async-push rejection handling. * * @category Interfaces */ export interface AsyncDuplexPipelineBuilderInterface< TCurrent, TStartTransfer extends InputTransfer, > { to( nextTransfer: DuplexTransfer, owned?: boolean, ): AsyncDuplexPipelineBuilderInterface; finish< TFinishTransfer extends DuplexTransfer, TTriggerable extends TriggerableInterface | undefined = undefined, TAsyncTriggerable extends AsyncTriggerableInterface | undefined = undefined, TGate extends GateInterface | undefined = undefined, >( lastTransfer: TFinishTransfer, options?: { triggerable?: TTriggerable; asyncTriggerable?: TAsyncTriggerable; gate?: TGate; owned?: boolean; linkOnError?: ErrorHandler; }, ): CompositeDuplexTransfer< InputTransferDataType, OutputTransferDataType, TStartTransfer, TFinishTransfer, TTriggerable, TAsyncTriggerable, TGate >; }