{"id":22087762,"url":"https://github.com/rainxh11/rxt","last_synced_at":"2025-09-19T01:04:13.853Z","repository":{"id":128273873,"uuid":"533319638","full_name":"rainxh11/RxT","owner":"rainxh11","description":".NET Reactive Types that provide similar functionalities inspired from: (reactive, ref \u0026 computed) found in Vue.js","archived":false,"fork":false,"pushed_at":"2022-09-10T16:08:30.000Z","size":49,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-09-16T09:00:58.889Z","etag":null,"topics":["computed","iobservable","observable","reactive","reactive-extensions","reactive-object","reactive-programming"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rainxh11.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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-09-06T12:45:22.000Z","updated_at":"2024-11-12T14:45:51.000Z","dependencies_parsed_at":"2023-03-22T07:02:58.480Z","dependency_job_id":null,"html_url":"https://github.com/rainxh11/RxT","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/rainxh11/RxT","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rainxh11%2FRxT","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rainxh11%2FRxT/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rainxh11%2FRxT/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rainxh11%2FRxT/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rainxh11","download_url":"https://codeload.github.com/rainxh11/RxT/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rainxh11%2FRxT/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275862844,"owners_count":25541902,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-18T02:00:09.552Z","response_time":77,"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":["computed","iobservable","observable","reactive","reactive-extensions","reactive-object","reactive-programming"],"created_at":"2024-12-01T02:06:35.117Z","updated_at":"2025-09-19T01:04:13.814Z","avatar_url":"https://github.com/rainxh11.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"![](https://raw.githubusercontent.com/rainxh11/RxT/master/RxT.svg)\n\n|Version|Downloads|\n|-|-|\n|[![Latest version](https://img.shields.io/nuget/v/RxT.svg)](https://www.nuget.org/packages/RxT/)|![Downloads](https://img.shields.io/nuget/dt/RxT.svg)|\n\n# Rx\\\u003cT\\\u003e\n.NET Reactive Types that provide similar functionalities inspired from: (`reactive`, `ref` \u0026 `computed`) found in **Vue.js**\n\n### This library provides 4 types: `Reactive\u003cT\u003e`, `ConcurrentReactive\u003cT\u003e`, `Computed\u003cT\u003e`, `Computed\u003cT,R\u003e`\n# Example Usage:\n## `Reactive\u003cT\u003e`\na reactive wrapper object that track changes of the underlying object it is wrapping.\n1. Create a reactive object:\n```csharp\nusing RxT;\n\nvar searchQuery = new Reactive\u003cstring\u003e(\"\");\n```\n2. Change the state:\n```csharp\nsearchQuery.Value = \"search\";\n```\n3. Track its state changes as an `IObservable\u003cT\u003e`\n```csharp\nsearchQuery\n    .Subscribe(x =\u003e Console.WriteLine($\"Search Query: {x}\"));\n```\n### There is also an additional `ConcurrentReactive\u003cT\u003e` a thread-safe version of `Reactive\u003cT\u003e`.\n## `Computed\u003cT\u003e`\na read-only reactive object that track changes of a `Reactive\u003cT\u003e` object while applying a custom filter to its underlying `IObservable\u003cT\u003e`\n\n1. Create a computed object from previous `searchQuery` with 500ms debouncing filter\n```csharp\nusing RxT;\n\nvar searchQuery = new Reactive\u003cstring\u003e(\"\");\nvar searchQueryDebounced = searchQuery\n                            .SpawnComputed(obs =\u003e obs.Throttle(500));\n```\n3. Track its state changes as an `IObservable\u003cT\u003e`\n```csharp\nsearchQueryDebounced\n    .Subscribe(x =\u003e Console.WriteLine($\"Search Query Debounced: {x}\"));\n```\n\nBoth `Reactive\u003cT\u003e` \u0026 `Computed\u003cT\u003e` implements the `IObservable\u003cT\u003e` interface\n\n## `Computed\u003cT,R\u003e`\nsame as `Computed\u003cT\u003e` but with different type for `Value`\n```csharp\nusing RxT;\n\nvar searchQuery = new Reactive\u003cstring\u003e(\"\");\nvar searchLength = searchQuery\n    .SpawnComputed(\n         // Transform function to apply each time state changes\n        query =\u003e query.Length,\n        obs =\u003e obs.DistinctUntilChanged());\n```\n\n## Changing values of nested properties:\nchanging `Reactive\u003cT\u003e.Value` value directly will only trigger state change if `T` is a primitive type or `string`, nested properties will not trigger any state change.\n\n### Solution:\nuse `Reactive\u003cT\u003e.Modify()` method\n```csharp\nusing RxT;\n\nvar pagination = new Reactive\u003cPagination\u003e(new Pagination()\n{\n    Page = 1,\n    PageSize = 25,\n    SortBy = \"+createdAt\"\n});\n\npagination.Modify((p, triggerChange) =\u003e\n{\n    p.Page = 2;\n    triggerChange();\n});\n\n\nrecord Pagination\n{\n    public int Page { get; set; }\n    public int PageSize { get; set; }\n    public string SortBy { get; set; }\n}\n```\nyou can also omit `triggerChange()` and state change will be triggered automatically\n```csharp\npagination.Modify(p =\u003e p.Page = 2);\n```\nsame thing can be done to `Computed\u003cT\u003e`, keep in mind it will change the source `Reactive\u003cT\u003e.Value` as it is passed by reference\n```csharp\npaginationComputed = pagination.SpawnComputed(obs =\u003e obs)\npaginationComputed.ModifySource(p =\u003e p.Page = 2);\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frainxh11%2Frxt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frainxh11%2Frxt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frainxh11%2Frxt/lists"}