Guacamole.SourceGenerators
0.1.0-alpha.41
dotnet add package Guacamole.SourceGenerators --version 0.1.0-alpha.41
NuGet\Install-Package Guacamole.SourceGenerators -Version 0.1.0-alpha.41
<PackageReference Include="Guacamole.SourceGenerators" Version="0.1.0-alpha.41" />
<PackageVersion Include="Guacamole.SourceGenerators" Version="0.1.0-alpha.41" />
<PackageReference Include="Guacamole.SourceGenerators" />
paket add Guacamole.SourceGenerators --version 0.1.0-alpha.41
#r "nuget: Guacamole.SourceGenerators, 0.1.0-alpha.41"
#:package Guacamole.SourceGenerators@0.1.0-alpha.41
#addin nuget:?package=Guacamole.SourceGenerators&version=0.1.0-alpha.41&prerelease
#tool nuget:?package=Guacamole.SourceGenerators&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
Learn more about Target Frameworks and .NET Standard.
This package has no dependencies.
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 | 753 | 12/17/2025 |
| 0.1.0-alpha.40 | 429 | 11/18/2025 |
| 0.1.0-alpha.39 | 307 | 10/28/2025 |
| 0.1.0-alpha.38 | 201 | 10/28/2025 |
| 0.1.0-alpha.37 | 197 | 10/28/2025 |
| 0.1.0-alpha.36 | 184 | 10/6/2025 |
| 0.1.0-alpha.34 | 196 | 10/6/2025 |
| 0.1.0-alpha.33 | 185 | 10/6/2025 |
| 0.1.0-alpha.32 | 179 | 10/6/2025 |
| 0.1.0-alpha.31 | 182 | 10/6/2025 |
| 0.1.0-alpha.30 | 512 | 10/4/2025 |
| 0.1.0-alpha.29 | 452 | 10/4/2025 |
| 0.1.0-alpha.28 | 453 | 10/3/2025 |
| 0.1.0-alpha.26 | 484 | 10/3/2025 |
| 0.1.0-alpha.25 | 492 | 10/3/2025 |
| 0.1.0-alpha.23 | 528 | 10/2/2025 |