Guacamole 0.1.0-alpha.41
dotnet add package Guacamole --version 0.1.0-alpha.41
NuGet\Install-Package Guacamole -Version 0.1.0-alpha.41
<PackageReference Include="Guacamole" Version="0.1.0-alpha.41" />
<PackageVersion Include="Guacamole" Version="0.1.0-alpha.41" />
<PackageReference Include="Guacamole" />
paket add Guacamole --version 0.1.0-alpha.41
#r "nuget: Guacamole, 0.1.0-alpha.41"
#:package Guacamole@0.1.0-alpha.41
#addin nuget:?package=Guacamole&version=0.1.0-alpha.41&prerelease
#tool nuget:?package=Guacamole&version=0.1.0-alpha.41&prerelease
Guacamole
A .NET framework for building incremental compilers and computation pipelines, inspired by Roslyn's incremental generators. Provides automatic dependency tracking, caching, and change propagation for efficient recomputation when inputs change.
Features
- Push-Based Reactive Architecture: External sources push data changes, triggering automatic recomputation
- Incremental Computation: Automatic dependency tracking and selective recomputation
- Provider-based API: Familiar Roslyn-style
IncrementalValueProvider<T>andIncrementalValuesProvider<T> - Source Generation: Generate context classes with push-based source accessors at compile time
- Thread-safe: Built-in reader/writer locking for concurrent access
- Dependency Injection: First-class DI support with Microsoft.Extensions.DependencyInjection
- Performance: LRU caching, optimized graph invalidation, comprehensive benchmarks
Quick Start
Install the packages:
dotnet add package Guacamole
dotnet add package Guacamole.SourceGenerators
Note:
Guacamoleprovides the core runtime functionality, whileGuacamole.SourceGeneratorscontains the source generators that create push-based source accessors at compile time. Both packages are required for full functionality.
Define a computing context:
using Guacamole;
[ComputingContext]
public partial class MyCompilerContext : ComputingContextBase
{
// Source property - generates SourceCodeSource accessor
public partial IncrementalValueProvider<string> SourceCode { get; }
// Derived computation
public IncrementalValueProvider<ParseTree> ParsedTree { get; }
public MyCompilerContext()
{
// Build computation pipeline
ParsedTree = SourceCode.Select(Parse);
}
private ParseTree Parse(string source) => /* ... */;
}
Use the push-based source API:
var context = new MyCompilerContext();
// Register output handler - called automatically when data changes
context.RegisterOutput(context.ParsedTree, (tree, ctx) =>
{
Console.WriteLine($"Parsed: {tree}");
});
// Push data through source - triggers automatic recomputation
context.SourceCodeSource.Set("let x = 42");
// Output handler called automatically - no SaveChanges() needed!
var result = context.ParsedTree.GetValue();
if (result.IsSuccess)
{
var tree = result.Value;
}
Provider Extension Methods
Guacamole provides a rich set of extension methods for building computation pipelines, similar to Roslyn's incremental generators:
IncrementalValueProvider<T> Extensions
// Transform a single value
provider.Select(x => x * 2)
provider.Select(x => x.ToString(), StringComparer.OrdinalIgnoreCase)
// Filter a single value
provider.Where(x => x > 0)
provider.Where(x => x.IsValid, customComparer)
// Combine two providers
first.Combine(second) // Returns IncrementalValueProvider<(TFirst, TSecond)>
// Transform to multiple values
provider.SelectMany(x => x.Children)
provider.SelectMany(x => x.Items, customComparer)
IncrementalValuesProvider<T> Extensions
// Transform each value
values.Select(x => x.Name)
values.Select(x => x.ToString(), customComparer)
// Filter values
values.Where(x => x.Age >= 18)
values.Where(x => x.IsActive, customComparer)
// Flatten nested collections
values.SelectMany(x => x.Tags)
values.SelectMany(x => x.Children, customComparer)
// Collect to immutable array
values.Collect() // Returns IncrementalValueProvider<ImmutableArray<T>>
// Combine with single value
values.Combine(singleValue) // Pairs each value with the single value
All methods support:
- Custom equality comparers for fine-grained cache control
- Automatic caching at each pipeline stage
- Lazy evaluation - computed only when accessed
- Dependency tracking - automatic invalidation when inputs change
Packages
Requirements
- .NET 10 RC1 or later
- C# 13
Building
dotnet build
Testing
dotnet test
Benchmarking
cd benchmarks/Guacamole.Benchmarks
dotnet run -c Release
Examples
See the examples/ directory for complete working examples:
BasicSourceUsage.cs- Fundamental push-based source usage patternsFileWatcherExample.cs- File system integration with incremental compilationDataPipelineExample.cs- Multi-stage data transformation pipeline
Run examples with:
dotnet script examples/BasicSourceUsage.cs
Architecture
Guacamole is built on three core concepts:
1. Push-Based Sources
External data sources push changes into the computation graph:
// Sources are auto-generated for each property
context.SourceFilesSource.Push(new SourceFile("Program.cs", "..."));
context.SourceFilesSource.Remove(oldFile);
context.SourceFilesSource.Replace(oldFile, newFile);
// Changes trigger automatic cache invalidation and recomputation
2. Computation Graph
Automatic dependency tracking and invalidation:
- Providers form a directed acyclic graph (DAG)
- Changes propagate through dependencies automatically
- LRU cache for computed values
- Thread-safe concurrent access
3. Incremental Providers
Immutable pipeline structures that lazily compute values:
IncrementalValueProvider<T>- Single value providerIncrementalValuesProvider<T>- Collection provider- Composable via extension methods (Select, Where, Combine, etc.)
- Automatic caching and dependency tracking
Source Generation
The source generators analyze [ComputingContext] classes and generate:
- Source accessor properties (e.g.,
NameSource,ItemsSource) - Push-based reactive sources (
IncrementalSource<T>,IncrementalValueSource<T>) - Automatic cache invalidation infrastructure
- Computation nodes for each provider in the graph
- Event subscriptions for change notifications
Key Differences from Mutation-Based Approaches
No SaveChanges Required:
// Old (mutation-based):
context.AddItem(item);
context.SaveChanges(); // Explicit commit
// New (push-based):
context.ItemsSource.Push(item); // Triggers automatically
Reactive by Default:
// Outputs trigger automatically when sources change
context.RegisterOutput(context.Results, (results, ctx) => {
// Called automatically when ItemsSource changes
});
Documentation
- Push-Based Architecture Research - Detailed architecture documentation
- Implementation Summary - Implementation overview
- Examples README - Guide to examples
License
MIT
| Product | Versions 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. |
-
net10.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.0-rc.1.25451.107)
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.41 | 767 | 12/17/2025 |
| 0.1.0-alpha.40 | 421 | 11/18/2025 |
| 0.1.0-alpha.39 | 309 | 10/28/2025 |
| 0.1.0-alpha.38 | 202 | 10/28/2025 |
| 0.1.0-alpha.37 | 193 | 10/28/2025 |
| 0.1.0-alpha.36 | 178 | 10/6/2025 |
| 0.1.0-alpha.34 | 181 | 10/6/2025 |
| 0.1.0-alpha.33 | 183 | 10/6/2025 |
| 0.1.0-alpha.32 | 182 | 10/6/2025 |
| 0.1.0-alpha.31 | 180 | 10/6/2025 |
| 0.1.0-alpha.30 | 179 | 10/4/2025 |
| 0.1.0-alpha.29 | 107 | 10/4/2025 |
| 0.1.0-alpha.28 | 126 | 10/3/2025 |
| 0.1.0-alpha.27 | 133 | 10/3/2025 |
| 0.1.0-alpha.26 | 139 | 10/3/2025 |
| 0.1.0-alpha.25 | 150 | 10/3/2025 |
| 0.1.0-alpha.23 | 184 | 10/2/2025 |