{"id":37031598,"url":"https://github.com/bowlerhats/sigsharp","last_synced_at":"2026-01-14T03:53:16.876Z","repository":{"id":287681725,"uuid":"953973141","full_name":"bowlerhats/sigsharp","owner":"bowlerhats","description":"A computational dependency library for .Net inspired by Angular signals.","archived":false,"fork":false,"pushed_at":"2025-11-08T07:52:12.000Z","size":135,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-11-08T08:13:49.292Z","etag":null,"topics":["computation","dotnet","effect","signal"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bowlerhats.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-03-24T11:20:26.000Z","updated_at":"2025-11-08T07:49:51.000Z","dependencies_parsed_at":null,"dependency_job_id":"5effd963-d00f-4e24-8150-d4d51d696ecc","html_url":"https://github.com/bowlerhats/sigsharp","commit_stats":null,"previous_names":["bowlerhats/sigsharp"],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/bowlerhats/sigsharp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bowlerhats%2Fsigsharp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bowlerhats%2Fsigsharp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bowlerhats%2Fsigsharp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bowlerhats%2Fsigsharp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bowlerhats","download_url":"https://codeload.github.com/bowlerhats/sigsharp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bowlerhats%2Fsigsharp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28408903,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T01:52:23.358Z","status":"online","status_checked_at":"2026-01-14T02:00:06.678Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["computation","dotnet","effect","signal"],"created_at":"2026-01-14T03:53:14.031Z","updated_at":"2026-01-14T03:53:16.866Z","avatar_url":"https://github.com/bowlerhats.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"SigSharp\n==========\n\nA computational dependency library for .Net inspired by Angular signals.\n\nSupports `Signal`, `Computed`, `Effect` constructs and collection signals (`HashSetSignal\u003c\u003e`, `DictionarySignal\u003c\u003e`)\nwith full reference and lifecycle tracking, memoization.\n\nSigSharp is intended to be used when you need complex calculation chains which are not deterministic or fast enough to be implemented with just using simple properties. \n\nSome example usage scenarios:\n- Complex financial calculations\n- Report data or model preparation\n- Model based generators\n- Complex state representations\n\n\nMinimal usage example\n---------------------\n\n```bash\n\u003e dotnet add package SigSharp\n```\n\n```C#\nusing SigSharp;\n\nvar calculator = new InvoiceCalculator();\n\ncalculator.InvoiceLinePrices.Add(4);\n\nConsole.WriteLine($\"Debug total: {calculator.InvoiceTotalDebug}\");\nConsole.Out.Flush();\n\n// second call to get property value will be memoized, not recomputed\nConsole.WriteLine($\"Debug total: {calculator.InvoiceTotalDebug}\");\nConsole.Out.Flush();\n\n/* Output:\nTotal updating...\nDebug total: 10\nTotal updated: 10\nDebug total: 10\n*/\n\nclass InvoiceCalculator\n{\n    public readonly HashSetSignal\u003cdouble\u003e InvoiceLinePrices = new([1, 2, 3]);\n\n    public double InvoiceTotal =\u003e this.Computed(() =\u003e InvoiceLinePrices.Sum());\n    \n    public double InvoiceTotalDebug =\u003e this.Computed(() =\u003e\n    {\n        Console.WriteLine(\"Total updating...\");\n        \n        return InvoiceTotal;\n    });\n\n    public InvoiceCalculator()\n    {\n        this.Effect(() =\u003e\n        {\n            Console.WriteLine($\"Total updated: {InvoiceTotal}\");\n            Console.Out.Flush();\n        });\n    }\n}\n\n\n```\n\nOther examples can be found in [Examples](./examples/SimpleDemo/Program.cs) folder\n\nFeatures / Goals\n--------\n\n- Healthy balance between ease of use and performance\n- Extensibility: letting you implement that last 5% you very much need for your project/usage\n- Self-contained and AOT compatible.\n\nKey concepts\n------------\n\nA `Signal` is a piece of data that can change, and those changes are tracked.\nFor example, tracked by a `ComputedSignal` which is a glorified memoized expression.\nWhen the system calculates the value of that expression and touches any signal (including other computed signals),\nit remembers to watch for changes of those signals. When any of the changes it marks itself dirty which indicates\nthat it needs to be recalculated next time someone asks for its value.\n\nAn `Effect` is a reaction to signal changes.\n\nIf you imagine all the dependencies between various signals, computations and effects,\nthen it forms a compute graph. Each of these elements form the nodes.\n`Signal`, `HashSetSignal\u003c\u003e`, etc. are primitive `signal nodes`, while `ComputedSignal` and `Effect` are `reactive nodes`.\n\nReactive nodes must be part of a `SignalGroup`. If you are using the extension methods, the group management is handled automatically for you.\nThe target (this param) of the extension methods act as `anchors` or in other words `keys` for implicit signal groups.\nThey are linked via a weakmap.\n\nOther notable features\n--------------\n\n1. `Untracked` support\n\nIn the example below the two public properties will be calculated once, because the reference to\nthe signal is explicitly untracked, so their value will never be dirty.\n```C#\nclass Some \n{\n    private Signal\u003cint\u003e dontReactToMe = new(0);\n    public int CalcOnce =\u003e this.Computed(() =\u003e dontReactToMe.Untracked);\n    public int CalcOnce2 =\u003e this.Computed(() =\u003e Signals.Untracked(() =\u003e dontReactToMe));\n}\n\n```\n\n2. Effect suspensions\n\nSuspensions are \"async local\", not global. They are useful when you want to batch together lot of changes.\n\n```C#\npublic async Task Load() \n{\n    await using var suspender = Signals.Suspend();\n    // do tons of loading, setting signals, etc.\n    \n    // at the end of loading the disposal\n    // of the suspender will resume the affected effects\n}\n```\n\n3. Disposed value access handling\n\nSignals can be configured how to behave after they are disposed. By default they try to \"remember\" their last scalar value.\n\n4. Weak effect and weak computation support\n\nWhen effects or computations have a reference to a state, that state can be a WeakRef, so\nthat the lifetime of these signals are tied to the WeakRef.\nIt should be rarely used, but useful in fire and forget scenarios.\n\n\n\nContributions\n-------------\nThis library is in alpha state. Despite the api surface being ready for release, many bug fixes and other major background chagnes might happen.\nSo until the library is in an alpha state, limited contributions will be accepted to not waste dev time.\n\nI kindly ask you to sign off the project's CLA, which provides legal ease-of-mind to You and fellow contributors.\nIn addition to the DCO, we ask you to grant us (project owners) permission to change the license of the project to other open source license if need be in the future.\nFor example we might want to change from the current Apache license to MIT or EPL in the future.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbowlerhats%2Fsigsharp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbowlerhats%2Fsigsharp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbowlerhats%2Fsigsharp/lists"}