Add benchmarks, source generators and multi-targeting#92
Merged
Conversation
Add a new Benchmarks project with Program.cs and BenchmarkDotNet setup for comparing Minimalist, System.Reactive and R3. Introduce two incremental source-generator projects (R3Bridge and SystemReactiveBridge) that emit opt-in bridge adapters when R3 or System.Reactive are referenced. Update Minimalist.Reactive.csproj to expand target frameworks (desktop, mobile, and .NET 9/10), add platform support properties, and include the generators as analyzer outputs for packaging. Update Directory.Build.props to include README in the NuGet package and add a global.json test runner. Modify tests project to target net9/net10, switch test/coverage tooling, add generator project references, and update the solution to include the new projects and configurations.
Introduce a new Signal{Factories}.cs providing an expanded factory surface for signals: Range, Repeat, Unfold, Use, FromEnumerable, FromTask, FromAsyncEnumerable (platform-guarded), After/Every/Interval/Pulse/Timer, Timer(dueTime,period), and collection combinators (Concat, Merge, Race, Zip, CombineLatest, ZipLatest, ForkJoin). Implement scheduler-aware behavior, validation checks, cancellation and disposal handling, and optimized fast-paths for completed/failed tasks. Also add [ExcludeFromCodeCoverage] to the Signal class and normalize header comments across several existing Signal files.
Add [ExcludeFromCodeCoverage] to internal signal classes and SignalsBase to omit them from test coverage. Also add new RangeSignal and RepeatSignal implementations (simple synchronous producers). Fix subscription ordering in CatchSignal to initialize the exception subscription before subscribing to the source to avoid a potential race. Minor header/whitespace normalization across files.
Introduce several new signal types and refactor core signal behavior for correctness and performance. Added: CommandSignal (async/sync command with results/faults/isRunning), KeepSignal and MapSignal (replacing internal Where/Select usage), ReadOnlyState and StateSignal (read-only and state helpers), and Map/Keep helpers. Reworked Signal<T> internals to simplify observer handling, add a direct-action subscription path, improve disposal/stop semantics, and replace array-based observer storage with a lightweight witness/list strategy. Optimized ReplaySignal to support a ring buffer for fixed-size replay and conditional time-windowing, plus various HasObservers/IsDisposed checks made more robust via ReferenceEquals. Applied ExcludeFromCodeCoverage attributes to multiple signal types and removed the old SelectSignal and WhereSignal implementations.
Introduce alias types (Slot, Pocket, AssignmentSlot) and refactor core disposable implementations. MultipleDisposable: replace ConcurrentBag with a locked List, add null/argument checks, make IsDisposed check consistent, ensure thread-safe add/remove and deterministic disposal of contained items. SingleDisposable: implement single-assignment semantics with locking, validate arguments, prevent double assignment, and ensure action is invoked when appropriate; expose a thread-safe IsDisposed. SingleReplaceableDisposable: avoid invoking the action unless a successful transition to disposed occurred. Disposable.Create: treat a null action as Empty for backward compatibility. Added ExcludeFromCodeCoverage attributes and other minor cleanups and null-safety improvements.
Add a new Witness static factory (Witness.cs) providing allocation-conscious Create and Safe observers with DelegateWitness and SafeWitness implementations. Introduce Moment<T> struct to represent timestamped values. Apply code-quality updates: mark several internal types with ExcludeFromCodeCoverage, seal classes (EmptyWitness, ListWitness, DisposedWitness, ThrowWitness, PriorityQueue), fix Spark<T> equality operator to avoid recursion and cache the completed spark instance, and return EmptyWitness.Instance from ListWitness.Remove. Minor formatting and documentation tweaks included.
Fix scheduling semantics and improve concurrency/cleanup across schedulers. Key changes: - Add System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage to various scheduler and virtual-time types. - Fix Schedule overloads in CurrentThreadScheduler and ImmediateScheduler to use the computed due TimeSpan instead of TimeSpan.Zero. - Rework ScheduledItem to use an IDisposable field with Interlocked operations for thread-safe disposal/state tracking, fix Invoke/Cancel/Dispose races and resource handling. - Add VirtualClock (VirtualTimeScheduler<DateTimeOffset, TimeSpan> implementation) and TestClock (test-facing alias) for deterministic virtual-time testing. These changes correct scheduling behavior, harden scheduled-item lifecycle handling against races, and provide a virtual clock for tests.
Introduce a comprehensive set of reactive operators and hot-sharing utilities. Adds ConnectableSignal<T> with Multicast/PublishLive/ReplayLive/ShareLive/RefCount/AutoConnect helpers and large operator collections in SignalOperatorMixins.cs and SignalOperatorParityMixins.cs (Map/Keep/Tap/Scan/Concat/Merge/Switch/Zip/CombineLatest/Throttle/Sample/Timeout/Collect/ToSignal/async helpers, parity aliases, etc.). Update LinqMixins to delegate Select/Where to the new Map/Keep implementations. Also include minor cleanup/formatting adjustments in ExceptionMixins.cs, Handle.cs, and SubscribeMixins.cs.
Replace xUnit with TUnit.Core across tests (update using directives and change [Fact] to [Test]) and add a lightweight Assert helper (Assert.cs). Add extensive new test suites to expand coverage (CoreRuntimeContractTests, CoverageCompletionTests, FactoryOperatorContractTests, StatefulSharingAndBridgeContractTests, etc.) and update existing tests (AsyncSignalTests, BehaviourSignalTests, ConcurencyTests, DisposableTests, ReplaySignalTests, SignalCreateTests, SignalFromTaskTest, SignalTests) to the new test framework. These changes migrate the test harness and increase runtime/operator/factory coverage and null-guard assertions.
Replaces the minimal placeholder README with a full project README. The new document describes project goals, design posture, installation, target frameworks, and runtime dependency policy; details core concepts (Signal<T>, observers/witnesses, disposables, stateful signals); lists creation factories, operators, composition helpers, schedulers, and spark materialization; documents source-generator bridges for System.Reactive and R3 and migration mappings; includes examples, performance notes, repository layout, validation/benchmark commands, a practical migration checklist, and license information.
Rename workflow to BuildOnly and replace the old Windows job with a streamlined windows-latest job. Remove manual Visual Studio install steps and legacy env outputs; switch to actions/checkout@v6 and actions/setup-dotnet with caching for multiple .NET versions (8/9/10 preview). Keep NBGV versioning, add setup-msbuild, use cache for ~/.nuget/packages and .nuke/temp, and run the repository build via ./build.cmd Compile. Replace the previous test/coverage and Codecov upload steps with a dotnet test run that emits cobertura XML and upload those results as an artifact. Overall cleanup: remove unused env vars/outputs, update action versions, and simplify the CI flow for faster, cacheable runs.
glennawatson
approved these changes
May 25, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add a new Benchmarks project with Program.cs and BenchmarkDotNet setup for comparing Minimalist, System.Reactive and R3. Introduce two incremental source-generator projects (R3Bridge and SystemReactiveBridge) that emit opt-in bridge adapters when R3 or System.Reactive are referenced. Update Minimalist.Reactive.csproj to expand target frameworks (desktop, mobile, and .NET 9/10), add platform support properties, and include the generators as analyzer outputs for packaging. Update Directory.Build.props to include README in the NuGet package and add a global.json test runner. Modify tests project to target net9/net10, switch test/coverage tooling, add generator project references, and update the solution to include the new projects and configurations.
Introduce a new Signal{Factories}.cs providing an expanded factory surface for signals: Range, Repeat, Unfold, Use, FromEnumerable, FromTask, FromAsyncEnumerable (platform-guarded), After/Every/Interval/Pulse/Timer, Timer(dueTime,period), and collection combinators (Concat, Merge, Race, Zip, CombineLatest, ZipLatest, ForkJoin). Implement scheduler-aware behavior, validation checks, cancellation and disposal handling, and optimized fast-paths for completed/failed tasks. Also add [ExcludeFromCodeCoverage] to the Signal class and normalize header comments across several existing Signal files.
Add [ExcludeFromCodeCoverage] to internal signal classes and SignalsBase to omit them from test coverage. Also add new RangeSignal and RepeatSignal implementations (simple synchronous producers). Fix subscription ordering in CatchSignal to initialize the exception subscription before subscribing to the source to avoid a potential race. Minor header/whitespace normalization across files.
Introduce several new signal types and refactor core signal behavior for correctness and performance. Added: CommandSignal (async/sync command with results/faults/isRunning), KeepSignal and MapSignal (replacing internal Where/Select usage), ReadOnlyState and StateSignal (read-only and state helpers), and Map/Keep helpers. Reworked Signal internals to simplify observer handling, add a direct-action subscription path, improve disposal/stop semantics, and replace array-based observer storage with a lightweight witness/list strategy. Optimized ReplaySignal to support a ring buffer for fixed-size replay and conditional time-windowing, plus various HasObservers/IsDisposed checks made more robust via ReferenceEquals. Applied ExcludeFromCodeCoverage attributes to multiple signal types and removed the old SelectSignal and WhereSignal implementations.
Introduce alias types (Slot, Pocket, AssignmentSlot) and refactor core disposable implementations. MultipleDisposable: replace ConcurrentBag with a locked List, add null/argument checks, make IsDisposed check consistent, ensure thread-safe add/remove and deterministic disposal of contained items. SingleDisposable: implement single-assignment semantics with locking, validate arguments, prevent double assignment, and ensure action is invoked when appropriate; expose a thread-safe IsDisposed. SingleReplaceableDisposable: avoid invoking the action unless a successful transition to disposed occurred. Disposable.Create: treat a null action as Empty for backward compatibility. Added ExcludeFromCodeCoverage attributes and other minor cleanups and null-safety improvements.
Add a new Witness static factory (Witness.cs) providing allocation-conscious Create and Safe observers with DelegateWitness and SafeWitness implementations. Introduce Moment struct to represent timestamped values. Apply code-quality updates: mark several internal types with ExcludeFromCodeCoverage, seal classes (EmptyWitness, ListWitness, DisposedWitness, ThrowWitness, PriorityQueue), fix Spark equality operator to avoid recursion and cache the completed spark instance, and return EmptyWitness.Instance from ListWitness.Remove. Minor formatting and documentation tweaks included.
Fix scheduling semantics and improve concurrency/cleanup across schedulers. Key changes:
These changes correct scheduling behavior, harden scheduled-item lifecycle handling against races, and provide a virtual clock for tests.
Introduce a comprehensive set of reactive operators and hot-sharing utilities. Adds ConnectableSignal with Multicast/PublishLive/ReplayLive/ShareLive/RefCount/AutoConnect helpers and large operator collections in SignalOperatorMixins.cs and SignalOperatorParityMixins.cs (Map/Keep/Tap/Scan/Concat/Merge/Switch/Zip/CombineLatest/Throttle/Sample/Timeout/Collect/ToSignal/async helpers, parity aliases, etc.). Update LinqMixins to delegate Select/Where to the new Map/Keep implementations. Also include minor cleanup/formatting adjustments in ExceptionMixins.cs, Handle.cs, and SubscribeMixins.cs.
Replace xUnit with TUnit.Core across tests (update using directives and change [Fact] to [Test]) and add a lightweight Assert helper (Assert.cs). Add extensive new test suites to expand coverage (CoreRuntimeContractTests, CoverageCompletionTests, FactoryOperatorContractTests, StatefulSharingAndBridgeContractTests, etc.) and update existing tests (AsyncSignalTests, BehaviourSignalTests, ConcurencyTests, DisposableTests, ReplaySignalTests, SignalCreateTests, SignalFromTaskTest, SignalTests) to the new test framework. These changes migrate the test harness and increase runtime/operator/factory coverage and null-guard assertions.
Replaces the minimal placeholder README with a full project README. The new document describes project goals, design posture, installation, target frameworks, and runtime dependency policy; details core concepts (Signal, observers/witnesses, disposables, stateful signals); lists creation factories, operators, composition helpers, schedulers, and spark materialization; documents source-generator bridges for System.Reactive and R3 and migration mappings; includes examples, performance notes, repository layout, validation/benchmark commands, a practical migration checklist, and license information.