Skip to content

hbtweb/alien-signals-cs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

alien-signals-cs

C# port of stackblitz/alien-signals 3.1.2. Line-for-line, same algorithm, same flags, same DLL semantics.

Why

alien-signals is a small reactive-signals library: signals, computed values, effects, an automatic dependency graph with pull-on-read and push-mark-dirty propagation. It was previously available only on JavaScript runtimes via npm. This artifact ports the same algorithm to .NET so any C#, F#, or ClojureCLR consumer can use it without a JS bridge.

Layout

src/AlienSignals/
  ReactiveFlags.cs       Bit-flag constants
  ReactiveNode.cs        Base node (Deps, DepsTail, Subs, SubsTail, Flags)
  Link.cs                Doubly-linked-list edge between dep and sub
  ReactiveSystem.cs      Algorithm core: Link, Unlink, Propagate,
                         CheckDirty, ShallowPropagate, StartTracking,
                         EndTracking (port of system.ts)
  SignalNode.cs          Generic Value + PreviousValue
  ComputedNode.cs        Generic Value + Getter
  EffectNode.cs          Fn
  Signal.cs              User-facing Get / Set
  Computed.cs            User-facing Get
  Effect.cs              User-facing Stop
  Signals.cs             Static facade: Signal, Computed, Effect, Batch,
                         Untrack, EffectScope, Trigger (port of index.ts)

Usage

using Hbt.AlienSignals;

var a = Signals.Signal(1);
var b = Signals.Computed<int>(prev => a.Get() * 2);
var e = Signals.Effect(() => Console.WriteLine(b.Get()));

a.Set(5);    // prints 10
Signals.Batch(() => {
    a.Set(7);
    a.Set(9);
});            // prints 18 once
e.Stop();

Build & test

dotnet build
dotnet test
# Passed!  - Failed:     0, Passed:    21

Test parity

21 xUnit tests cover the load-bearing cases ported from upstream's Vitest spec files:

  • signal read/write semantics, value-equality skip
  • computed memoisation and chained propagation
  • effect lifecycle (eager run, dispose, nested stop)
  • batch coalescing
  • untrack via Signals.Untrack and via direct SetActiveSub
  • diamond topology — both signal-only and computed-via-checkDirty
  • signal-revert: writing then reverting must NOT force recompute
  • effectScope dispose

Threading

Single-threaded, same as upstream. Static state on Signals (activeSub, activeScope, batchDepth, notify queue) is not synchronised. Use Signals.Reset() to clear state between tests or REPL evaluations within a single process.

C#-specific notes

  • Generics carry the value type (SignalNode<T>, ComputedNode<T>). The engine callbacks see non-generic ReactiveNode and reach the closed-generic Update*Generic<T> methods via reflection. Cold paths only.
  • static Signals uses a static constructor for lazy initialisation of the algorithm core, accommodating the unwatched callback's self-reference.
  • Targets net6.0. Any modern .NET (Core 3.0+, .NET 5+, 6+, 8+) consumes the resulting Hbt.AlienSignals.dll.

Versioning

Tracks upstream npm. When stackblitz publishes a new version, this artifact moves to the same version with the corresponding system.ts and index.ts changes ported.

License

MIT — same as upstream.

About

C# port of [stackblitz/alien-signals 3.1.2](https://github.com/stackblitz/alien-signals).

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages