Functario.Caravel.Core.Extensions 0.1.0-alpha

This is a prerelease version of Functario.Caravel.Core.Extensions.
dotnet add package Functario.Caravel.Core.Extensions --version 0.1.0-alpha
                    
NuGet\Install-Package Functario.Caravel.Core.Extensions -Version 0.1.0-alpha
                    
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="Functario.Caravel.Core.Extensions" Version="0.1.0-alpha" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Functario.Caravel.Core.Extensions" Version="0.1.0-alpha" />
                    
Directory.Packages.props
<PackageReference Include="Functario.Caravel.Core.Extensions" />
                    
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 Functario.Caravel.Core.Extensions --version 0.1.0-alpha
                    
#r "nuget: Functario.Caravel.Core.Extensions, 0.1.0-alpha"
                    
#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 Functario.Caravel.Core.Extensions@0.1.0-alpha
                    
#: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=Functario.Caravel.Core.Extensions&version=0.1.0-alpha&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Functario.Caravel.Core.Extensions&version=0.1.0-alpha&prerelease
                    
Install as a Cake Tool

Caravel

⚠️Warning!

Caravel is a pre‑release framework. The public API, documentation and internal implementation are still evolving, and breaking changes may occur in future releases.

Caravel is a framework that provides an abstraction for creating and navigating graphs. Enabling developers to define relationships between nodes and traverse them efficiently using Dijkstra's algorithm for shortest path calculations.

Table of Contents:

Getting Started

  1. Define your nodes implementing INode.
  2. Create a graph using DijkstraGraph.
  3. Initialize a journey with a starting node.
  4. Navigate using fluent methods like .GotoAsync<T>() or .DoAsync<T>().
  5. Optionally document your journey and graph using Mermaid tools.

[↑ top]

Creating Nodes and Journeys

Defining Nodes

Each node must implement the INode interface:

using System.Collections.Immutable;
using Caravel.Abstractions;
using Caravel.Core.Extensions;

internal sealed class Node1 : INode
{
    public ImmutableHashSet<IEdge> GetEdges()
    {
		// Extension method 'CreateEdge' is a helper
		// to create a new 'Edge'.
        return [
            this.CreateEdge(OpenNode2),
            this.CreateEdge(OpenNode3)
        ];
    }

    private static Task<Node2> OpenNode2(IJourney journey, CancellationToken cancellationToken) =>
        Task.FromResult(new Node2());

    private static Task<Node3> OpenNode3(IJourney journey, CancellationToken cancellationToken) =>
        Task.FromResult(new Node3());

    public Task OnNodeVisitedAsync(IJourney journey, CancellationToken cancellationToken)
    {
        // Add your own logic
        return Task.CompletedTask;
    }
}

[↑ top]

Creating a Journey

	// Create the nodes
	var node1 = new Node1();
	var node2 = new Node2();
	var node3 = new Node3();
	INode[] nodes = [node1, node2, node3];

	// Generate the graph
	var routeFactory = new RouteFactory();
	var edgeFactory = new EdgeFactory();
	var graph = new DijkstraGraph(nodes, routeFactory, edgeFactory);

	// Create the Journey with default configuration
	var journeyConfiguration = JourneyConfigurationFactory.Create(
        JourneyLegHandlingOptions.InMemory,
        TimeProvider.System);

	var journey = new Journey(
        startingNode: node1,
        graph,
        journeyConfiguration,
        CancellationToken.None
    );

[↑ top]

Example Usage

	// Use a journey with Node1 as starting node to goto Node3.
	// Perform some action in the context of Node3
	// then go back to Node1.
	
	await journey
        .GotoAsync<Node3>()
        .DoAsync<Node3>((node3, cancellationToken) =>
        {
            // Perform some action on Node3
            return Task.FromResult(node3);
        })
        .GotoAsync<Node1>();

    var navigationSequence = await journey.ToMermaidSequenceDiagramMarkdownAsync();

The navigationSequence will contain the following Mermaid sequence diagram:

sequenceDiagram
Node1->>Node3:0
Node3->>Node3:0
Node3->>Node1:0
sequenceDiagram
Node1->>Node3:0
Node3->>Node3:0
Node3->>Node1:0

Note: Copy the above code into a .md file and open it in a markdown viewer that supports Mermaid to visualize the diagram or use Mermaid Live Editor to paste the code and see the rendered diagram.

[↑ top]

Key Features

Graph Navigation with Dijkstra Algorithm

Caravel supports the creation of weighted and unweighted graphs through Caravel.Graph.Dijkstra. Using Dijkstra's algorithm, it can compute the shortest route from any node to another, making it ideal for applications requiring optimal pathfinding.

[↑ top]

Step-by-Step Node Navigation

With methods like GotoAsync<TDestination>, Caravel allows step-by-step navigation through a graph. Each node implements INode.GetEdges() to declare its neighbors and transitions, enabling fluent navigation patterns.

[↑ top]

Waypoints & Exclusion Rules

Navigation can be controlled using:

  • Waypoints: Nodes that must be traversed in a specified order.
  • ExcludedWaypoints: Nodes that should be avoided during pathfinding.

This makes complex routing logic flexible and maintainable.

[↑ top]

Node Lifecycle Events

When a node is visited by Caravel, INode.OnNodeVisitedAsync() is invoked. This allows for:

  • Validation (e.g., waiting for prerequisites)
  • Logging or monitoring
  • Dynamic behavior based on node state (e.g., retrying on failure, set a flag on first visit, etc.)

[↑ top]

Contextual Actions in Nodes

Caravel supports executing actions within the context of the current node using DoAsync<TCurrentNode> or transitioning to another node via DoAsync<TCurrentNode, TTargetNode>. This enables rich workflows with side-effects and dynamic navigation.

GotoDoAsync<TOriginNode, TTargetNode> can be used to combine navigation and action in a single step. It navigates to TOriginNode and performs the specified action returning TTargnetNode. TTargnetNode can be the same as TOriginNode to perform actions without changing nodes.

[↑ top]

Cancellation & Timeout Management

Each journey has a global timeout (JourneyCancellationToken) that applies across all operations. Scoped cancellation tokens can be passed to individual actions for fine-grained control while still respecting the overall timeout.

Documentation via Mermaid

Caravel integrates seamlessly with Mermaid.js for documentation:

  • Graph Diagrams: Visualize the entire graph structure.
  • Sequence Diagrams: Document navigation flows and action sequences.
  • Support for metadata, relative nodes positions, and custom descriptions.

[↑ top]

UI Automation Ready

Caravel is compatible with Page Object Models (POM) and tools like Playwright, making it suitable for automating UI journeys in web or desktop applications.

Caravel should also be benific when using BDD frameworks like Reqnroll since you can write steps in a declarative way and let Caravel manages the navigation.

before

Given Anthony is logged in
When he clicks on `CreateMeeting` button
And he creates a meeting
And the meeting should be saved

after

With 'And he creates a meeting' StepDefinitions containing a 'journey.GotoDo<MeetingPage>(...)'.

Given Anthony is logged in
And he creates a meeting
Then the meeting should be saved

[↑ top]

Remarks

  • Caravel is not thread-safe. A parallelized navigation does not make much sense. If you need to perform concurrent navigations, create separate IJourney instances for each thread.
  • Use global using file with references to Caravel namespaces to simplify your code files:
global using Caravel.Abstractions;
global using Caravel.Abstractions.Exceptions;
global using Caravel.Core.Configurations;
global using Caravel.Core.Extensions;
global using Caravel.Mermaid;
global using static Caravel.Mermaid.GraphExtensions;
global using static Caravel.Mermaid.JourneyExtensions;
global using static Caravel.Mermaid.RouteExtensions;

[↑ top]

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  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.0-alpha 358 8/26/2025

- Initial alpha release.