Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE]: Add documentation deploy #23

Merged
merged 3 commits into from
Aug 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 6 additions & 10 deletions Hyperbee.Pipeline.sln
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hyperbee.Pipeline.Tests", "test\Hyperbee.Pipeline.Tests\Hyperbee.Pipeline.Tests.csproj", "{17DA1657-DF82-440F-B1F1-D888BFA9626B}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{884A8242-351E-4363-9B34-E8C202CF7787}"
ProjectSection(SolutionItems) = preProject
docs\childPipeline.md = docs\childPipeline.md
docs\dependencyInjection.md = docs\dependencyInjection.md
docs\execution.md = docs\execution.md
docs\middleware.md = docs\middleware.md
docs\todo.md = docs\todo.md
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hyperbee.Pipeline.Caching", "src\Hyperbee.Pipline.Caching\Hyperbee.Pipeline.Caching.csproj", "{833A7497-542F-4B88-A76A-DA520E000F6F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hyperbee.Pipeline.Caching.Tests", "test\Hyperbee.PipelineCaching.Tests\Hyperbee.Pipeline.Caching.Tests.csproj", "{B7E5FBB3-AF2A-4E48-8E6A-10887DC6C4C0}"
Expand All @@ -49,6 +40,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hyperbee.Pipeline.Auth.Test
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hyperbee.Pipeline.Benchmark", "test\Hyperbee.Pipleline.Benchmark\Hyperbee.Pipeline.Benchmark.csproj", "{4117A842-A068-41DD-AA16-AE158025EA9A}"
EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "docs", "docs\docs.shproj", "{FC3B0A95-4DA0-43A0-A19D-624152BDF2F6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -91,12 +84,15 @@ Global
{1FA7CE2A-C9DA-4DC3-A242-5A7EAF8EE4FC} = {870D9301-BE3D-44EA-BF9C-FCC2E87FE4CD}
{4DBDB7F5-3F66-4572-80B5-3322449C77A4} = {1FA7CE2A-C9DA-4DC3-A242-5A7EAF8EE4FC}
{17DA1657-DF82-440F-B1F1-D888BFA9626B} = {F9B24CD9-E06B-4834-84CB-8C29E5F10BE0}
{884A8242-351E-4363-9B34-E8C202CF7787} = {870D9301-BE3D-44EA-BF9C-FCC2E87FE4CD}
{B7E5FBB3-AF2A-4E48-8E6A-10887DC6C4C0} = {F9B24CD9-E06B-4834-84CB-8C29E5F10BE0}
{3E5F6864-2BAD-4349-8C7A-D199A715FA3C} = {F9B24CD9-E06B-4834-84CB-8C29E5F10BE0}
{4117A842-A068-41DD-AA16-AE158025EA9A} = {F9B24CD9-E06B-4834-84CB-8C29E5F10BE0}
{FC3B0A95-4DA0-43A0-A19D-624152BDF2F6} = {870D9301-BE3D-44EA-BF9C-FCC2E87FE4CD}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {32874F5B-B467-4F28-A8E2-82C2536FB228}
EndGlobalSection
GlobalSection(SharedMSBuildProjectFiles) = preSolution
docs\docs.projitems*{fc3b0a95-4da0-43a0-a19d-624152bdf2f6}*SharedItemsImports = 13
EndGlobalSection
EndGlobal
29 changes: 29 additions & 0 deletions docs/_config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
title: Hyperbee Pipeline
description: Documentation for Hyperbee Pipeline.
remote_theme: pmarsceill/just-the-docs
baseurl: "/hyperbee.json/"
url: "https://stillpoint-software.github.io"

aux_links:
"GitHub Repository":
- "//github.com/Stillpoint-Software/hyperbee.pipeline"

footer_content: |
<div>
<span>&copy; <span id="copyright-year"></span> <a href='https://www.stillpointsoftware.net/'>Stillpoint Software</a>.</span>
<script>
document.getElementById("copyright-year").textContent = new Date().getFullYear();
</script>
</div>

exclude:
- todo.md

# logo: "/assets/icon.png"
search_enabled: true # Enable search

# External navigation links
nav_external_links:
- title: Stillpoint Software
url: https://www.stillpointsoftware.net/
opens_in_new_tab: true
3 changes: 3 additions & 0 deletions docs/_includes/nav_footer_custom.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<footer class="site-footer">
Hyperbee Json Docs
</footer>
6 changes: 6 additions & 0 deletions docs/childPipeline.md
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
---
layout: default
title: Hyperbee Pipeline
nav_order: 3
---

# Child Pipleline
6 changes: 6 additions & 0 deletions docs/dependencyInjection.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
---
layout: default
title: Hyperbee Pipeline
nav_order: 3
---

# Dependency Injection

## Dependency Injection
Expand Down
22 changes: 22 additions & 0 deletions docs/docs.projitems
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<MSBuildAllProjects Condition="'$(MSBuildVersion)' == '' Or '$(MSBuildVersion)' &lt; '16.0'">$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
<HasSharedItems>true</HasSharedItems>
<SharedGUID>fc3b0a95-4da0-43a0-a19d-624152bdf2f6</SharedGUID>
</PropertyGroup>
<PropertyGroup Label="Configuration">
<Import_RootNamespace>docs</Import_RootNamespace>
</PropertyGroup>
<ItemGroup>
<None Include="$(MSBuildThisFileDirectory)childPipeline.md" />
<None Include="$(MSBuildThisFileDirectory)dependencyInjection.md" />
<None Include="$(MSBuildThisFileDirectory)execution.md" />
<None Include="$(MSBuildThisFileDirectory)index.md" />
<None Include="$(MSBuildThisFileDirectory)middleware.md" />
<None Include="$(MSBuildThisFileDirectory)_config.yml" />
</ItemGroup>
<ItemGroup>
<Content Include="$(MSBuildThisFileDirectory)_includes\nav_footer_custom.html" />
</ItemGroup>
</Project>
13 changes: 13 additions & 0 deletions docs/docs.shproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Globals">
<ProjectGuid>fc3b0a95-4da0-43a0-a19d-624152bdf2f6</ProjectGuid>
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" />
<PropertyGroup />
<Import Project="docs.projitems" Label="Shared" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" />
</Project>
6 changes: 5 additions & 1 deletion docs/execution.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@

---
layout: default
title: Hyperbee Pipeline
nav_order: 2
---

# Execution

Expand Down
227 changes: 227 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
---
layout: default
title: Hyperbee Pipeline
nav_order: 1
---

# Hyperbee.Pipeline

`Hyperbee.Pipeline` allows you to construct asynchronous fluent pipelines in .NET. A pipeline, in this context, refers to a
sequence of data processing elements arranged in series, where the output of one element serves as the input for the subsequent
element.

Hyperbee pipelines are composable, reusable, and easy to test. They are designed to be used in a variety of scenarios, such
as data processing, message handling, and workflow automation.

Some key features are:

* Middleware
* Hooks
* Wraps
* Conditional flows
* Loops
* Parallel processing
* Dependency injection
* Early returns and cancellation
* Child pipelines


```csharp
// Takes a string and returns a number
var question = PipelineFactory
.Start<string>()
.PipeIf((ctx, arg) => arg == "Adams", builder => builder
.Pipe((ctx, arg) => 42)
.Cancel()
)
.Pipe((ctx, arg) => 0)
.Build();

var answer1 = await question(new PipelineContext(), "Adams");
Assert.AreEqual(42, answer1);

var answer2 = await question(new PipelineContext(), "Smith");
Assert.AreEqual(0, answer2);
```

## Hook

The `Hook` and `HookAsync` methods allow you to add a hook that is called for every statement in the pipeline. This hook takes the current context, the current argument, and a delegate to the next part of the pipeline. It can manipulate the argument before and after calling the next part of the pipeline.

Here's an example of how to use `HookAsync`:

```csharp
var command = PipelineFactory
.Start<string>()
.HookAsync( async ( ctx, arg, next ) => await next( ctx, arg + "{" ) + "}" )
.Pipe( ( ctx, arg ) => arg + "1" )
.Pipe( ( ctx, arg ) => arg + "2" )
.Build();

var result = await command( new PipelineContext() );

Assert.AreEqual( "{1}{2}", result );
```

## Wrap

The `Wrap` and `WrapAsync` method allows you to wrap a part of the pipeline. This is useful when you want to apply a transformation to only a part of the pipeline.

Here’s an example of how to use `WrapAsync`:

```csharp
var command = PipelineFactory
.Start<string>()
.Pipe( ( ctx, arg ) => arg + "1" )
.Pipe( ( ctx, arg ) => arg + "2" )
.WrapAsync( async ( ctx, arg, next ) => await next( ctx, arg + "{" ) + "}" )
.Pipe( ( ctx, arg ) => arg + "3" )
.Build();

var result = await command( new PipelineContext() );

Assert.AreEqual( "{12}3", result );

```

## Dependency Injection

Sometimes Pipelines and Pipeline middleware need access to specific container services. This can be
accomplished by registering services with the `PipelineContextFactory`. This can be done through
DI configuration, or manually through the `PipelineContextFactoryProvider` if you are not using DI.

Pipelines manage dependencies with a specialized container. This allows the implementor to control
the services that are exposed through the pipeline. If you want to expose all application
services then you can call `AddPipeline` and pass `includeAllServices: true`.

Register pipelines with DI and provide Pipeline dependencies using the application container.

```csharp
services.AddPipeline( includeAllServices: true );
```

Register Pipelines with DI and provide Pipeline dependencies using a specialized container.

```csharp
services.AddPipeline( (factoryServices, rootProvider) =>
{
factoryServices.AddTransient<IThing>()
factoryServices.ProxyService<IPrincipalProvider>( rootProvider ); // pull from root container
} );
```

## Advanced Features

The `PipelineFactory` library provides a variety of helper methods that allow you to customize the behavior of your pipelines. These methods provide powerful functionality for manipulating data as it passes through the pipeline.

### Reduce

The `Reduce` and `ReduceAsync` methods allow you to reduce a sequence of elements to a single value. You can specify a reducer function that defines how the elements should be combined, and a builder function that creates the pipeline for processing the elements.

### WaitAll

The `WaitAll` method allows you to wait for all pipelines to complete before continuing. You can specify a set of builders that create the pipelines to wait for, a reducer function that combines the results of the pipelines.

```csharp
var count = 0;

var command = PipelineFactory
.Start<int>()
.WaitAll( builders => builders.Create(
builder => builder.Pipe( ( ctx, arg ) => Interlocked.Increment( ref count ) ),
builder => builder.Pipe( ( ctx, arg ) => Interlocked.Increment( ref count ) )
),
reducer: ( ctx, arg, results ) => { return arg + results.Sum( x => (int) x.Result ); }
)
.Build();

var result = await command( new PipelineContext() );

Assert.AreEqual( 2, count );
Assert.AreEqual( 3, result );
```

### PipeIf

The `PipeIf` method allows you to conditionally add a step to the pipeline. You can specify a condition function that determines whether the step should be added, a builder function that creates the step, and an optional flag indicating whether middleware should be inherited.

### ForEach and ForEachAsync

The `ForEach` and `ForEachAsync` methods allow you to apply a pipeline to each element in a sequence. You can specify a builder function that creates the pipeline for processing the elements.

```csharp
var count = 0;

var command = PipelineFactory
.Start<string>()
.Pipe( ( ctx, arg ) => arg.Split( ' ' ) )
.ForEach<string>( builder => builder
.Pipe( ( ctx, arg ) => count += 10 )
)
.Pipe( ( ctx, arg ) => count += 5 )
.Build();

await command( new PipelineContext(), "e f" );

Assert.AreEqual( count, 25 );
```

### Call and CallAsync

The `Call` and `CallAsync` methods allow you to add a procedure to the pipeline. You can think of these as `Action<T>` and `Pipe` like `Func<T>`.

In this example notice that `arg + 9` is not returned from the use of `Call`

```csharp
var callResult = string.Empty;

var command = PipelineFactory
.Start<string>()
.Pipe( ( ctx, arg ) => arg + "1" )
.Pipe( ( ctx, arg ) => arg + "2" )
.Call( builder => builder
.Call( ( ctx, arg ) => callResult = arg + "3" )
.Pipe( ( ctx, arg ) => arg + "9" )
)
.Pipe( ( ctx, arg ) => arg + "4" )
.Build();

var result = await command( new PipelineContext() );

Assert.AreEqual( "124", result );
Assert.AreEqual( "123", callResult );
```

### Chaining Child Pipelines

The `PipelineFactory` library allows you to chain pipelines together. Since pipelines are just functions, they can be used as input to other pipelines. This allows you to create complex data processing flows by reusing and chaining together multiple pipelines.

Here's an example of how to chain pipelines together:

```csharp
var command2 = PipelineFactory
.Start<string>()
.Pipe( ( ctx, arg ) => $"{arg} again!" )
.Build();

var command1 = PipelineFactory
.Start<string>()
.Pipe( ( ctx, arg ) => $"hello {arg}" )
.PipeAsync( command2 )
.Build();

var result = await command1( new PipelineContext(), "pipeline" );

Assert.AreEqual( "hello pipeline again!", result );
```

## Credits

Hyperbee.Pipeline is built upon the great work of several open-source projects. Special thanks to:

- [Just The Docs](https://github.com/just-the-docs/just-the-docs) for the documentation theme.

## Contributing

We welcome contributions! Please see our [Contributing Guide](https://github.com/Stillpoint-Software/.github/blob/main/.github/CONTRIBUTING.md)
for more details.
5 changes: 5 additions & 0 deletions docs/middleware.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
---
layout: default
title: Hyperbee Pipeline
nav_order: 4
---

# Middleware
Pipelines support custom middleware. Custom middleware can be created by implementing an extension method that uses a `Hook` or `Wrap` builder.
Expand Down
Loading
Loading