diff --git a/Hyperbee.Pipeline.sln b/Hyperbee.Pipeline.sln
index 2868451..6ba5ee6 100644
--- a/Hyperbee.Pipeline.sln
+++ b/Hyperbee.Pipeline.sln
@@ -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}"
@@ -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
@@ -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
diff --git a/docs/todo.md b/docs/.todo.md
similarity index 55%
rename from docs/todo.md
rename to docs/.todo.md
index 2df92b5..6ae0945 100644
--- a/docs/todo.md
+++ b/docs/.todo.md
@@ -1,23 +1,18 @@
-# Things TODO
+# todo
-## Improve GitHub Workflows
- - PR process
- - Branch creation
- - Auto Release
- - Auto Version
+## Builder generic type arg names
-### Builder generic type arg names
Consider refactoring the builder generic type args to be more clear. It is a difficult naming problem
because the inputs of the current builder and the inputs of the builder being created overlap. Naming of
-type args that make sense in both contexts has proven difficult. The compositional nature of pipelines
+type args that make sense in both contexts has proven difficult. The compositional nature of pipelines
is also a complicating factor; `TInput`, for instance, isn't the input to the current builder but is the
-first input to the pipeline.
+first input to the pipeline.
The current argument convention is [`TInput`, `TOutput`, `TNext`] where:
-* `TInput` is always the initial pipeline input
-* `TOutput` is the _current_ builder output (the next function's input)
-* `TNext` is the next function output
+- `TInput` is always the initial pipeline input
+- `TOutput` is the _current_ builder output (the next function's input)
+- `TNext` is the next function output
-Should `TInput` be renamed to `TStart` or `TFirst`?
-Should `TNext` be renamed to make it clear that it is the next `TOutput`?
\ No newline at end of file
+Should `TInput` be renamed to `TStart` or `TFirst`?
+Should `TNext` be renamed to make it clear that it is the next `TOutput`?
diff --git a/docs/_config.yml b/docs/_config.yml
new file mode 100644
index 0000000..7069d67
--- /dev/null
+++ b/docs/_config.yml
@@ -0,0 +1,26 @@
+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: |
+
+
+# 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
diff --git a/docs/_includes/nav_footer_custom.html b/docs/_includes/nav_footer_custom.html
new file mode 100644
index 0000000..7bb117a
--- /dev/null
+++ b/docs/_includes/nav_footer_custom.html
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/docs/childPipeline.md b/docs/childPipeline.md
index 0722696..62b0c42 100644
--- a/docs/childPipeline.md
+++ b/docs/childPipeline.md
@@ -1 +1,7 @@
+---
+layout: default
+title: Hyperbee Pipeline
+nav_order: 3
+---
+
# Child Pipleline
diff --git a/docs/dependencyInjection.md b/docs/dependencyInjection.md
index a71f44f..027abf6 100644
--- a/docs/dependencyInjection.md
+++ b/docs/dependencyInjection.md
@@ -1,3 +1,9 @@
+---
+layout: default
+title: Hyperbee Pipeline
+nav_order: 3
+---
+
# Dependency Injection
## Dependency Injection
diff --git a/docs/docs.projitems b/docs/docs.projitems
new file mode 100644
index 0000000..7003fca
--- /dev/null
+++ b/docs/docs.projitems
@@ -0,0 +1,22 @@
+
+
+
+ $(MSBuildAllProjects);$(MSBuildThisFileFullPath)
+ true
+ fc3b0a95-4da0-43a0-a19d-624152bdf2f6
+
+
+ docs
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/docs.shproj b/docs/docs.shproj
new file mode 100644
index 0000000..9426a01
--- /dev/null
+++ b/docs/docs.shproj
@@ -0,0 +1,13 @@
+
+
+
+ fc3b0a95-4da0-43a0-a19d-624152bdf2f6
+ 14.0
+
+
+
+
+
+
+
+
diff --git a/docs/execution.md b/docs/execution.md
index 268931b..3d676c2 100644
--- a/docs/execution.md
+++ b/docs/execution.md
@@ -1,4 +1,8 @@
-
+---
+layout: default
+title: Hyperbee Pipeline
+nav_order: 2
+---
# Execution
diff --git a/docs/index.md b/docs/index.md
new file mode 100644
index 0000000..a0569c1
--- /dev/null
+++ b/docs/index.md
@@ -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()
+ .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()
+ .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()
+ .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()
+ factoryServices.ProxyService( 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()
+ .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()
+ .Pipe( ( ctx, arg ) => arg.Split( ' ' ) )
+ .ForEach( 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` and `Pipe` like `Func`.
+
+In this example notice that `arg + 9` is not returned from the use of `Call`
+
+```csharp
+var callResult = string.Empty;
+
+var command = PipelineFactory
+ .Start()
+ .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()
+ .Pipe( ( ctx, arg ) => $"{arg} again!" )
+ .Build();
+
+var command1 = PipelineFactory
+ .Start()
+ .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.
diff --git a/docs/middleware.md b/docs/middleware.md
index fb92a2b..3d99e4f 100644
--- a/docs/middleware.md
+++ b/docs/middleware.md
@@ -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.
diff --git a/src/Hyperbee.Pipeline/Hyperbee.Pipeline.csproj b/src/Hyperbee.Pipeline/Hyperbee.Pipeline.csproj
index 34b7227..8066f99 100644
--- a/src/Hyperbee.Pipeline/Hyperbee.Pipeline.csproj
+++ b/src/Hyperbee.Pipeline/Hyperbee.Pipeline.csproj
@@ -25,10 +25,6 @@
-
- True
- \
-
True
\
diff --git a/src/Hyperbee.Pipeline/README.md b/src/Hyperbee.Pipeline/README.md
index d0e94cd..5e397bd 100644
--- a/src/Hyperbee.Pipeline/README.md
+++ b/src/Hyperbee.Pipeline/README.md
@@ -1,7 +1,25 @@
# Hyperbee.Pipeline
-The `Hyperbee.Pipeline` library is a sophisticated tool for constructing 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.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
diff --git a/test/Hyperbee.Pipeline.Auth.Tests/Hyperbee.Pipeline.Auth.Tests.csproj b/test/Hyperbee.Pipeline.Auth.Tests/Hyperbee.Pipeline.Auth.Tests.csproj
index 9b4fdb4..75faf26 100644
--- a/test/Hyperbee.Pipeline.Auth.Tests/Hyperbee.Pipeline.Auth.Tests.csproj
+++ b/test/Hyperbee.Pipeline.Auth.Tests/Hyperbee.Pipeline.Auth.Tests.csproj
@@ -15,8 +15,8 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
+
+
diff --git a/test/Hyperbee.Pipeline.Tests/Hyperbee.Pipeline.Tests.csproj b/test/Hyperbee.Pipeline.Tests/Hyperbee.Pipeline.Tests.csproj
index 1d767de..81759aa 100644
--- a/test/Hyperbee.Pipeline.Tests/Hyperbee.Pipeline.Tests.csproj
+++ b/test/Hyperbee.Pipeline.Tests/Hyperbee.Pipeline.Tests.csproj
@@ -4,9 +4,9 @@
false
-
+
-
+
diff --git a/test/Hyperbee.PipelineCaching.Tests/Hyperbee.Pipeline.Caching.Tests.csproj b/test/Hyperbee.PipelineCaching.Tests/Hyperbee.Pipeline.Caching.Tests.csproj
index 10d03a0..f42e14f 100644
--- a/test/Hyperbee.PipelineCaching.Tests/Hyperbee.Pipeline.Caching.Tests.csproj
+++ b/test/Hyperbee.PipelineCaching.Tests/Hyperbee.Pipeline.Caching.Tests.csproj
@@ -15,9 +15,9 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
-
+