fsprojects/FSharp.Data.Adaptive
59.9
Adequate · 24 September 2026
23.7k
lines of production code
F#
primary language
5
measurements over time
What this system is
FSharp.Data.Adaptive is a library that provides reactive, incremental data structures for .NET, including adaptive lists, sets, maps, and values. It enables efficient state management by automatically tracking dependencies and computing minimal deltas when underlying data changes, rather than recomputing entire results. The system supports both functional and mutable interaction patterns, with dedicated APIs for C\# interoperability and browser-based execution via Fable.
Features
Added C\# interop demo and benchmarks
A new demo project at src/Demo/CSharpInterop demonstrates the C\# interoperability features of the F\# Data Adaptive library, including usage of FSharpHashSet, FSharpHashMap, and Changeable collections with transaction support, alongside BenchmarkDotNet benchmarks comparing performance of different iteration methods.
src/Demo/CSharpInterop · high confidence
Added EventInterop demo for adaptive file system watching
A new example project at src/Demo/EventInterop demonstrates how to adaptively watch a directory and keep a console output up-to-date using the adaptive system. The demo includes a FileSystem module that uses a FileSystemWatcher to push file creation, modification, deletion, and rename events into an adaptive map, alongside a background thread that processes these changes. The project references Aardvark.Build in addition to FSharp.Core.
src/Demo/EventInterop · high confidence
Added demo project to verify trimmed publishing support
A new demo project, src/Demo/PublishTrimmedTest, has been added to validate the library's compatibility with .NET trimming. This project references FSharp.Core and Aardvark.Build and includes a minimal F\# script that demonstrates reactive value mapping and transaction updates, serving as a test case for the trimmed publishing workflow.
src/Demo/PublishTrimmedTest · high confidence
Core adaptive evaluation engine and callback system
The library introduces the foundational \AdaptiveObject\ and \IAdaptiveObject\ types, which manage the dependency graph, evaluation levels, and dirty tracking. It adds \AdaptiveToken\ to handle caller context and cancellation during eager evaluation, and implements \AfterEvaluateCallbacks\ to run actions after evaluation completes. The \Callbacks\ module provides a thread-safe callback system using \MultiCallbackObject\ and \WeakOutputSet\ to ensure callbacks are properly GC'd and executed without memory leaks or deadlocks.
src/FSharp.Data.Adaptive/Core · high confidence
Demo application for adaptive file system queries
Added a new demo in the FileSystem location that demonstrates using FSharp.Data.Adaptive to maintain a single adaptive list of lines across all files in a directory. The application uses AdaptiveDirectory and AdaptiveFile to read file contents and subscribes to changes, pretty-printing additions, removals, and updates to the console as files are created, modified, or deleted.
src/Demo/FileSystem · high confidence
Fable browser demo for FSharp.Data.Adaptive
A new Fable-based demo application has been added to the FSharp.Data.Adaptive library, allowing users to run the reactive data structures (AVal, ASet, AMap, AList) directly in a web browser. The demo includes a Webpack build configuration and an HTML entry point that exercises core library features such as value mapping, set unions, and change tracking via a reader.
src/Demo/Fable · high confidence
Introduces AdaptiveReduction and Traceable infrastructure for incremental updates
This change adds the \AdaptiveReduction\ module and type, providing operators for efficiently reducing collections (such as ASet, AMap, and AList) adaptively. It includes combinators for parallel reductions (\par\, \structpar\), mapping inputs/outputs (\mapIn\, \mapOut\), and constructing reductions from group-like or fold-like functions. Pre-built reductions are now available for counting elements (\count\, \countPositive\, \countNegative\), finding minimums/maximums (\tryMin\, \tryMax\), and computing arithmetic aggregates (\sum\, \product\, \average\). Additionally, the \Traceable\ module is introduced to support incremental state management, defining interfaces for applying deltas (\tapplyDelta\), computing deltas between states (\tcomputeDelta\), and managing history pruning (\tprune\).
FSharp.Data.Adaptive · high confidence
Introduces core adaptive data structures and delta computation
Adds the foundational data structures for the library, including \IndexList\, \Index\, \HashMap\, and \HashSet\, along with their corresponding delta types (\IndexListDelta\, \HashMapDelta\, \HashSetDelta\). This enables users to compute and apply incremental changes to collections, with \IndexList\ providing efficient order-maintenance for list-like structures and the hash collections supporting reference-counted delta operations.
src/FSharp.Data.Adaptive/Datastructures · high confidence
Introduction of Adaptive HashSet (ASet) and Changeable HashSet (CSet)
This change introduces the \ASet\ (adaptive set) and \CSet\ (changeable adaptive set) data structures to the library. \ASet\ provides a functional, reactive set implementation with support for adaptive operations such as \map\, \filter\, \union\, \difference\, \reduce\, and \fold\, allowing users to build reactive pipelines over set data. \CSet\ provides a mutable wrapper around an adaptive set, implementing \ICollection\<'T\>\ and \ISet\<'T\>\ (on non-Fable targets), enabling users to mutate the set's contents while maintaining adaptive tracking. The implementation includes internal optimizations for reductions and dirty tracking, and supports Fable compilation.
src/FSharp.Data.Adaptive/AdaptiveHashSet · high confidence
Introduction of AdaptiveIndexList and ChangeableIndexList with extensive functional operators
This change introduces the \AdaptiveIndexList\ module, providing a new adaptive list data structure (\alist\<'T\>\) and a mutable variant (\ChangeableIndexList\<'T\>\ or \clist\<'T\>\). The \alist\ type exposes a rich set of functional operators for adaptive data manipulation, including \map\, \choose\, \filter\, \collect\, \bind\, \reduce\, \sort\, and \sub\ (slicing), allowing users to build reactive pipelines over list data. The \ChangeableIndexList\ implementation allows user code to mutate the list state via methods like \UpdateTo\, \Append\, \Prepend\, and \InsertAt\, while automatically tracking changes for dependent adaptive values. Additionally, the diff includes \AdaptiveFileSystem\ helpers for watching file system changes adaptively.
src/FSharp.Data.Adaptive/AdaptiveIndexList · high confidence
Introduction of AdaptiveReduction and core AdaptiveValue types
This change introduces the \AdaptiveReduction\ struct and module, providing composable reduction operations (such as \count\, \sum\, \average\, \min\, \max\, and \product\) that support incremental updates via \add\ and \sub\ functions. It also establishes the core \AdaptiveValue\ types, including the \IAdaptiveValue\ interface, the \ChangeableValue\ (\cval\) for mutable inputs, and the \AVal\ module with functions like \map\, \bind\, and \mapNonAdaptive\ for building dependency-aware computations.
src/FSharp.Data.Adaptive/AdaptiveValue · high confidence
Introduction of ChangeableModel collections and evaluation callbacks
The library now provides ChangeableModelList, ChangeableModelMap, and ChangeableLazyVal to manage collections and values where the underlying data changes but the container identity remains stable, allowing for efficient incremental updates via delta computation. Additionally, evaluation callbacks (AddCallback/AddWeakCallback) have been added to adaptive values and readers, enabling users to register side effects that trigger automatically when values change or when transaction finalizers run.
src/FSharp.Data.Adaptive · high confidence
Introduction of adaptive map (amap) and changeable map (cmap) data structures
This change introduces the \amap\ (adaptive map) and \cmap\ (changeable adaptive map) types, providing a new way to manage key-value collections that automatically track and propagate changes. The \amap\ type exposes a rich functional API via the \AMap\ module, including adaptive mapping (\map\, \mapA\), filtering (\filter\, \filterA\), combining (\union\, \intersect\), and reduction operations (\reduce\, \fold\). The \cmap\ type allows users to mutate the map directly (via \Add\, \Remove\, \UpdateTo\) while maintaining adaptive consistency with the rest of the system. These structures integrate with the existing \aval\ and \History\ mechanisms, enabling efficient, incremental updates for map-based state.
src/FSharp.Data.Adaptive/AdaptiveHashMap · high confidence
Introduction of traceable data structures and history management
The library now includes a new \Traceable\ module providing reference-counted, traceable implementations of core data structures (\CountingHashSet\, \HashMap\, \IndexList\) and a \History\ system. This enables users to track granular changes (deltas) and maintain versioned state histories for adaptive values, supporting features like undo/redo or incremental updates by exposing the underlying operations that modified the data.
src/FSharp.Data.Adaptive/Traceable · high confidence
New C\#-friendly API for adaptive collections and values
The \src/CSharp.Data.Adaptive\ module now provides a comprehensive set of C\#-optimized extension methods and static wrappers for the underlying F\# adaptive data structures. Users can now interact with \AList\, \ASet\, \AMap\, and \AVal\ using familiar C\# patterns, including LINQ-style extension methods like \Map\, \Filter\, \Where\, \Select\, and \SelectMany\. The API also exposes adaptive-specific operations such as \MapAdaptive\, \Bind\, \Bind2\, \Bind3\, and \MapUse\ for handling reactive updates, along with utility methods for managing callbacks (\AddCallback\, \AddWeakCallback\) and transaction management (\Transact\, \UseTransaction\). Additionally, C\#-friendly builders (\AdaptiveIndexListBuilder\, \AdaptiveHashMapBuilder\, \AdaptiveHashSetBuilder\) and a base class \AbstractAdaptiveObject\ are provided to simplify integration and evaluation within C\# applications.
src/CSharp.Data.Adaptive · high confidence
New scratchpad sketches for adaptive data structures and observability
The \src/Demo/Scratch\ directory has been populated with several new experimental modules demonstrating advanced usage of the \FSharp.Data.Adaptive\ library. \ABag.fs\ introduces an adaptive bag implementation supporting both constant and dynamic content via a \Unique\ identifier cache. \LookupAll.fs\ provides a sketch for n-ary lookups, enabling database-like joins between adaptive lists and maps. \Observable.fs\ adds extension methods to convert adaptive collections (\alist\, \aset\, \amap\, \aval\) into standard .NET \IObservable\ streams for reactive integration. Additionally, \AListSub.fs\ contains tests for list subsetting logic, and \ChangeableModelListList.fs\ demonstrates a changeable model list pattern.
src/Demo/Scratch · high confidence
Removals
Removed test helper module from core library
The \Test\ module, which previously contained a simple \timesTwo\ helper function, has been removed from the \FsIncremental.Core\ namespace. This cleanup eliminates unused internal test utilities from the main library code.
src/FsIncremental · high confidence
Behavioural changes
Project renamed to FSharp.Data.Adaptive with .NET 8 and modernized build
The library has been renamed from FsIncremental to FSharp.Data.Adaptive, reflected in the new solution file (FSharp.Data.Adaptive.sln) and updated README. The project now targets .NET 8.0, enforced by a new global.json SDK constraint, and the build system has been modernized by removing the legacy FAKE build.fsx script in favor of standard dotnet tooling (dotnet tool restore, dotnet paket restore, dotnet build).
(repo-wide) · high confidence
Refactored caching and transaction queue internals for performance and Fable compatibility
The internal caching mechanism in Cache.fs has been rewritten to use value options and tuples, introducing a new TryRevoke API that safely handles revocation without throwing exceptions, which resolves previous memory leaks when re-using transactions. Additionally, the transaction scheduling system now utilizes a specialized TransactQueue implementation (replacing the generic PriorityQueue) to improve commit performance, and the Utilities module includes Fable-specific compatibility fixes such as custom reference equality operators and shallow equality helpers.
src/FSharp.Data.Adaptive/Utilities · high confidence
Test coverage
Added reference implementations and property-based tests for adaptive collections; Removed obsolete test files and configuration.
Dependencies
Migration to .NET 8 and adoption of trimming support
The project has upgraded its target framework from .NET Core 2.2 to .NET 8 across the main library, C\# interop layer, and demo applications. This update enables .NET Native AOT trimming for the F\# and C\# libraries, allowing for smaller deployment sizes. Additionally, the test suite has migrated from xUnit to NUnit, and the Fable demo now uses updated Webpack tooling.
(dependencies) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
Score
- CAI 56 → 60 (+3.7)
- Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.
Lenses
- Code Health 61 → 69 (+8.2)
- Architecture 96 → 96 (-0.4)
- Maturity 50 → 53 (+3.3)
- Readiness 55 → 55 (+0.0)
- Security 69 → 81 (+12.1)
Resolved (238)
- ABag.choose (cognitive 16) (src/Demo/Scratch/ABag.fs)
- ABag.collect (cognitive 48) (src/Demo/Scratch/ABag.fs)
- ABag.collect (cyclomatic 19) (src/Demo/Scratch/ABag.fs)
- ABag.filter (cognitive 16) (src/Demo/Scratch/ABag.fs)
- ABag.ofAList (cognitive 28) (src/Demo/Scratch/ABag.fs)
- ABag.ofASet (cognitive 18) (src/Demo/Scratch/ABag.fs)
- ABag.sortByInternal (cognitive 31) (src/Demo/Scratch/ABag.fs)
- ABag.sortWith (cognitive 24) (src/Demo/Scratch/ABag.fs)
- ABag.unionMany' (cognitive 19) (src/Demo/Scratch/ABag.fs)
- AList.[AList] sub random (cognitive 27) (src/Test/FSharp.Data.Adaptive.Tests/AList.fs)
- AList.[MapExt] neighbours (cognitive 20) (src/Test/FSharp.Data.Adaptive.Tests/AList.fs)
- AListSub.run (cognitive 27) (src/Demo/Scratch/AListSub.fs)
- AMap.[AMap] reference impl (cognitive 18) (src/Test/FSharp.Data.Adaptive.Tests/AMap.fs)
- ASet.[ASet] mapA/flattenA/chooseA async (cognitive 17) (src/Test/FSharp.Data.Adaptive.Tests/ASet.fs)
- ASet.[ASet] ofSetTree (cognitive 34) (src/Test/FSharp.Data.Adaptive.Tests/ASet.fs)
- DeltaOperationList.ofArrayMyers (cognitive 31) (src/Test/FSharp.Data.Adaptive.Tests/Benchmarks/ListDeltaBenchmarks.fs)
- DeltaOperationList.ofArrayMyers (cyclomatic 17) (src/Test/FSharp.Data.Adaptive.Tests/Benchmarks/ListDeltaBenchmarks.fs)
- DeltaOperationList.ofArrayMyersBackup (cognitive 33) (src/Test/FSharp.Data.Adaptive.Tests/Benchmarks/ListDeltaBenchmarks.fs)
- DeltaOperationList.ofArrayMyersBackup (cyclomatic 18) (src/Test/FSharp.Data.Adaptive.Tests/Benchmarks/ListDeltaBenchmarks.fs)
- Dependency hygiene not measured — no packages were read
- …and 218 more
New (227)
- Documentation: no contributor guidance (README.md)
- Documentation: no installation or build instructions (README.md)
- Documentation: no usage examples (README.md)
- Duplicated block (10 lines × 2) (src/CSharp.Data.Adaptive/HashSet.fs)
- Duplicated block (10 lines × 2) (src/FSharp.Data.Adaptive/AdaptiveHashMap/AdaptiveHashMap.fs)
- Duplicated block (10 lines × 2) (src/FSharp.Data.Adaptive/AdaptiveHashMap/AdaptiveHashMap.fs)
- Duplicated block (10 lines × 2) (src/FSharp.Data.Adaptive/AdaptiveHashSet/AdaptiveHashSet.fs)
- Duplicated block (10 lines × 2) (src/FSharp.Data.Adaptive/CollectionExtensions.fs)
- Duplicated block (10 lines × 2) (src/FSharp.Data.Adaptive/Datastructures/HashCollections.fs)
- Duplicated block (10 lines × 2) (src/FSharp.Data.Adaptive/Datastructures/HashCollections.fs)
- Duplicated block (10 lines × 2) (src/FSharp.Data.Adaptive/Datastructures/IndexList.fs)
- Duplicated block (10 lines × 2) (src/FSharp.Data.Adaptive/Datastructures/IndexList.fs)
- Duplicated block (10 lines × 2) (src/FSharp.Data.Adaptive/Datastructures/MapExt.fs)
- Duplicated block (10 lines × 2) (src/FSharp.Data.Adaptive/Datastructures/MapExt.fs)
- Duplicated block (10 lines × 2) (src/FSharp.Data.Adaptive/Datastructures/MapExt.fs)
- Duplicated block (10 lines × 2) (src/FSharp.Data.Adaptive/Traceable/CountingHashSet.fs)
- Duplicated block (10 lines × 3) (src/FSharp.Data.Adaptive/Datastructures/IndexListDelta.fs)
- Duplicated block (10–11 lines × 2) (src/FSharp.Data.Adaptive/AdaptiveHashMap/AdaptiveHashMap.fs)
- Duplicated block (10–11 lines × 2) (src/FSharp.Data.Adaptive/Datastructures/MapExt.fs)
- Duplicated block (10–11 lines × 3) (src/FSharp.Data.Adaptive/AdaptiveHashMap/AdaptiveHashMap.fs)
- …and 207 more
Changes since last survey
- 6 commits — 4 feature/other, 2 fixes
By area
- (root) — 3 commits
- src/FSharp.Data.Adaptive — 2 commits
- (repo) — 1 commit
Notable commits
- fix: Fix AddCallback deadlock under concurrent transactions (#120)
- fix: Merge pull request #121 from fsprojects/fix/callback-deadlock-120
- change: ASet.single/ofSeq/ofList/ofArray/ofHashSet: eager constants, no Lazy/closure wrap
- change: added Difference to C# ASet extensions
- change: updated RELEASE_NOTES.md
- change: updated release notes
Architecture
- Containers 0 added · 0 removed · contexts 0 added · 2 removed · edges 0 added · 0 removed
Removed bounded contexts (2)
- EventInterop
- Scratch
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
fsprojects/FSharp.Data.Adaptive was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 24 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 76afc00027b10933606e733ff6258275c53224b3 — the exact code this score is about.
- Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-923689c465cf.