Steelax.Pufflow.Operators 0.1.4

dotnet add package Steelax.Pufflow.Operators --version 0.1.4
                    
NuGet\Install-Package Steelax.Pufflow.Operators -Version 0.1.4
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Steelax.Pufflow.Operators" Version="0.1.4" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Steelax.Pufflow.Operators" Version="0.1.4" />
                    
Directory.Packages.props
<PackageReference Include="Steelax.Pufflow.Operators" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Steelax.Pufflow.Operators --version 0.1.4
                    
#r "nuget: Steelax.Pufflow.Operators, 0.1.4"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Steelax.Pufflow.Operators@0.1.4
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Steelax.Pufflow.Operators&version=0.1.4
                    
Install as a Cake Addin
#tool nuget:?package=Steelax.Pufflow.Operators&version=0.1.4
                    
Install as a Cake Tool

Steelax.Pufflow

Steelax.Pufflow Steelax.Pufflow

Pufflow โ€” a library for building dataflow pipelines based on Poll and Push data transfer models and their combinations.


๐Ÿ“ฆ Installation

dotnet add package Steelax.Pufflow

๐Ÿง  Concept

The library defines 4 fundamental interfaces for passing data between pipeline components:

Poll (pull)

The Poll interface is the read side (output). Data is requested by the consumer.

Synchronous Asynchronous
IConsumator<T> IAsyncConsumator<T>
public interface IConsumator<T>
{
    ReadResult TryRead(out T value);   // non-blocking read
    bool WaitToRead();                 // blocking wait
}

public interface IAsyncConsumator<T>
{
    ReadResult TryRead(out T value);       // non-blocking read
    ValueTask<bool> WaitToReadAsync();     // async wait
}

Push (write)

The Push interface is the write side (input). Data is sent by the producer.

Synchronous Asynchronous
IProducator<T> IAsyncProducator<T>
public interface IProducator<T>
{
    WriteResult TryWrite(T value);    // non-blocking write
    bool WaitToWrite();               // blocking wait
    void Complete(Exception? ex);     // completion / error signal
}

public interface IAsyncProducator<T>
{
    WriteResult TryWrite(T value);         // non-blocking write
    ValueTask<bool> WaitToWriteAsync();    // async wait
    void Complete(Exception? ex);          // completion / error signal
}

Operation Results

ReadResult โ€” a 3-state discriminated union:

State Meaning implicit bool
Ready Value successfully read true
Nothing No data yet, stream is still active false
Completed Stream has ended, no more data false

WriteResult โ€” a 2-state discriminated union:

State Meaning implicit bool
Success Value successfully written true
Overflow Buffer is full false

Both results implicitly convert to bool for convenient use with [MaybeNullWhen(false)].


๐Ÿ—๏ธ Pipeline Components

Components in Pufflow fall into 3 roles:

flowchart LR
    subgraph Source
        SRC["Data source<br/>exposes poll output"]
    end
    subgraph Pipe
        PIPE_IN["Push input<br/>(IProducator / IAsyncProducator)"]
        PIPE_OUT["Poll output<br/>(IConsumator / IAsyncConsumator)"]
    end
    subgraph Sink
        SNK["Push input<br/>(IProducator / IAsyncProducator)<br/>terminator"]
    end

    SRC -->|"poll"| PIPE_IN
    PIPE_OUT -->|"poll"| SNK
Role Marker Type Description
Source Source<T> A component that only emits data (poll output)
Sink Sink<T> A component that only accepts data (push input) and terminates the pipeline
Pipe Pipe<TLeft, TRight> A transformer: push input โ†’ poll output

Sync/Async Markers

Explicit sync/async mode markers:

// Sync / Async โ€” zero-size structs
public struct Sync;
public struct Async;

Corresponding flow markers:

Type Description
Source<T> Poll data source of type T
Source<TKind, T> Source with Sync or Async tag
Sink<T> Push data sink of type T
Sink<TKind, T> Sink with Sync or Async tag
Pipe<TLeft, TRight> Transformer push-TLeft โ†’ poll-TRight
Pipe<TKind, TLeft, TRight> Transformer with Sync or Async tag

๐Ÿ”Œ How It Works

1. Define a component with the [Flow] attribute

using Steelax.Pufflow;
using Steelax.Pufflow.Abstractions;

[Flow]
public class MySource
{
    // Source: emits integers via poll interface
    public IConsumator<int> GetConsumator(FlowContext ctx)
    {
        // ... implementation
    }
}

[Flow]
public class MyTransform
{
    // Pipe: accepts int via push, emits string via poll
    public IConsumator<string> Handle(IProducator<int> input, FlowContext ctx)
    {
        // ... implementation
    }
}

[Flow]
public class MySink
{
    // Sink: accepts string via push and terminates the pipeline
    public void Execute(IProducator<string> input, FlowContext ctx)
    {
        // ... implementation
    }
}

2. Source Generator produces IFlowable<TFlow>

At compile time, the GetFlowGenerator analyzes the component's public methods and generates an implementation of IFlowable<Source<T>> / IFlowable<Pipe<TLeft, TRight>> / IFlowable<Sink<T>>.

3. Connect components via FlowExt

using static Steelax.Pufflow.FlowExt;

var pipeline = source
    .Next(transform)    // Source<T1> โ†’ Pipe<T1, T2> โ†’ Source<T2>
    .Next(sink);        // Source<T2> โ†’ Sink<T2> โ†’ Sink<T2>

4. Run the pipeline with FlowSource

using var flowSource = new FlowSource(cancellationToken);

// Attach a component to FlowSource
var source = mySource.Attach(flowSource);   // Source<T>

๐Ÿงฉ Supported Combinations

Components can mix poll and push in any combination:

Component Push Input Poll Output Handler Method
Source โŒ IConsumator<T> / IAsyncConsumator<T> GetConsumator, GetEnumerator
Source โŒ IEnumerator<T> / IAsyncEnumerator<T> GetEnumerator, GetAsyncEnumerator
Pipe IProducator<T> IConsumator<T> Handle, GetConsumator
Pipe IAsyncProducator<T> IAsyncConsumator<T> Handle, GetAsyncConsumator
Pipe IProducator<T> IAsyncConsumator<T> Handle
Pipe IEnumerator<T> / IAsyncEnumerator<T> IConsumator<T> / IAsyncConsumator<T> Handle, GetConsumator
Sink IProducator<T> / IAsyncProducator<T> โŒ Execute, ExecuteAsync

Note: IEnumerator<T> and IAsyncEnumerator<T> are standard .NET interfaces. Pufflow supports them as a special case of the poll model for compatibility.


๐Ÿšฐ Lifecycle Management

// FlowSource provides cancellation for the entire pipeline
using var flowSource = new FlowSource();

// Create context with a cancellation token
using var flowSource = new FlowSource(cancellationToken);

// Manual cancellation
flowSource.Context.Cancel();

// Automatic cancellation on Dispose
flowSource.Dispose();

๐Ÿงช Current Status

Feature Status
Async poll chain (IAsyncEnumerator) โœ… Implemented
Async poll chain (IAsyncConsumator) ๐Ÿšง In progress
Sync poll chain (IConsumator) ๐Ÿšง In progress
Push chain (IProducator / IAsyncProducator) ๐Ÿšง In progress
Pollโ†”Push combinations (Pipe) ๐Ÿšง In progress
Source Generator ([Flow] โ†’ IFlowable<>) โœ… Implemented

๐Ÿ“‹ Requirements

  • .NET 10.0+
  • C# 13+

๐Ÿ› ๏ธ Build

dotnet build
dotnet test
Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.4 38 8/13/2026
0.1.3 35 8/13/2026

Initial pre-release.