{"id":14956394,"url":"https://github.com/ali77gh/telescope","last_synced_at":"2025-10-24T09:30:47.321Z","repository":{"id":65956698,"uuid":"499215248","full_name":"ali77gh/Telescope","owner":"ali77gh","description":"A better state manager for flutter","archived":false,"fork":false,"pushed_at":"2023-04-06T10:13:42.000Z","size":1098,"stargazers_count":42,"open_issues_count":5,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-14T12:01:08.709Z","etag":null,"topics":["dart","flutter","observable","state-management"],"latest_commit_sha":null,"homepage":"https://pub.dev/packages/telescope","language":"Dart","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/ali77gh.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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}},"created_at":"2022-06-02T16:45:06.000Z","updated_at":"2024-10-17T20:04:47.000Z","dependencies_parsed_at":"2024-09-29T06:18:18.088Z","dependency_job_id":null,"html_url":"https://github.com/ali77gh/Telescope","commit_stats":{"total_commits":72,"total_committers":1,"mean_commits":72.0,"dds":0.0,"last_synced_commit":"9752204a761015a77658d77e90e2722da2748a98"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ali77gh%2FTelescope","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ali77gh%2FTelescope/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ali77gh%2FTelescope/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ali77gh%2FTelescope/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ali77gh","download_url":"https://codeload.github.com/ali77gh/Telescope/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":237944100,"owners_count":19391588,"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","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":["dart","flutter","observable","state-management"],"created_at":"2024-09-24T13:12:57.906Z","updated_at":"2025-10-24T09:30:41.915Z","avatar_url":"https://github.com/ali77gh.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Telescope\n\u003cimg src=\"https://raw.githubusercontent.com/ali77gh/Telescope/master/telescope.png\" height=\"200\" width=\"200\"\u003e \u003cbr\u003e\nEasy to use \u003cb\u003eState manager\u003c/b\u003e for flutter based on observer:eyes: design pattern.\n\n``` Telescope is more than a normal observer. ```\n\nTelescope:telescope:\n\u003cbr\u003e\n0. Supports all platforms.\n1. Easy to learn:book: \n   1. You can learn it in 5-10 min by reading README.\n   2. Also see [examples](https://github.com/ali77gh/Telescope/tree/master/example/lib). \n   3. Full dart standard documentation [here](https://pub.dev/documentation/telescope/latest/telescope/telescope-library.html).\n2. Feature rich:hearts: \n   1. Can directly bind to Flutters StateFullWidget and rebuild:recycle: widget on value change.\n   2. Save states on disk and load when needed.\n   3. Telescopes can watch each other with dependsOn() constructor.\n   4. Depends on can be async.\n   5. Caching ability with expireTime option.\n   6. debounceTime option (something like rx-js debounceTime).\n   7. Request a feature [here](https://github.com/ali77gh/Telescope/issues).\n3. Make it harder to make bugs:beetle::no_entry:.\n   1. With separation of concerns:raised_hands:.\n   2. No setState() needed:no_good:.\n4. Fast:zap: (just rebuild widgets that need to rebuild).\n5. Lightweight:hatched_chick: (less then 900KB)\n6. Flexible:ocean:\n   1. It lets you do it in your way as a library (not a framework):muscle:.\n   2. Can be used beside other state managers:couple:.\n\n### Installation:\n```bash\nflutter pub add telescope\n```\n\n### Import:\n```dart\nimport 'package:telescope/telescope.dart';\n```\n\n# How to use\nIn 3 steps.\n\n### 1. Make a telescope instance:\n```dart\nvar textValue = Telescope(\"default value\");\n```\n\n### 2. Watch(this):\nPut this in middle of you widget build function.\u003cbr\u003e\n```dart\n@override\nWidget build(BuildContext context) {\n  return Material(\n      child: SafeArea(\n          child: Container(\n            child: Column(children: [\n              // watch like this ('this' is State that will automatically rebuild on data change)\n              Text(textValue.watch(this)), \n              Text(textValue.watch(this)),\n              Text(textValue.watch(this).length.toString()),\n            ],),\n          )\n      )\n  );\n}\n```\n\nNote: You can watch one telescope instance from multiple widgets([example](https://github.com/ali77gh/Telescope/tree/master/example/lib/05_share_telescope_as_param)).\n\n### 3. Update value:\nYou can update telescope.value from anywhere in your code:\n\n```dart\nonTap: (){\n  textValue.value += \"a\";\n}\n```\n\n### Boom:\nAnd the widget will get update automatically without calling setState.\n\n\u003cimg src=\"https://raw.githubusercontent.com/ali77gh/Telescope/master/telescope.gif\"\u003e \u003cbr\u003e\n\nYou can also subscribe to observable by passing callback like a normal observable.\n```dart\ntextValue.subscribe((newValue){\n    // execute on value change\n});\n```\n\n### Non Builtin Types\nJust implement hashCode getter:\n```dart\nclass Human{\n   int height;\n   int weight;\n   Human(this.height,this.weight);\n\n   @override\n   int get hashCode =\u003e height*weight;\n}\n```\nAnd you are good to go:\n```dart\nvar human = Telescope\u003cHuman\u003e(null);\n```\n\n\n# Other features:\n\n### Depends on:\nTelescopes can be depended on other telescopes.\n\n```dart\nvar height = Telescope(186);\nvar weight = Telescope(72);\n\nvar bmi = Telescope.dependsOn([height,weight], () {\n  return weight.value / ((height.value/100) * (height.value/100));\n});\n\nvar showingText  = Telescope.dependsOn([bmi], () {\n  return \"weight is ${weight.value} and height is ${height.value} so bmi will be ${bmi.value.toString().substring(0,5)}\";\n});\n```\n\nSo when ever height or weight value get changes, the bmi will calculate itself because it depends on height and weight.\u003cbr\u003e\nAnd showingText will calculate itself too, because it depends on bmi.\n\n\u003cbr\u003e\n\n#### Async way:\n```dart\nvar bmi = Telescope.dependsOnAsync(0, [height, weight], () async {\n  return await calculateBMI(height.value, weight.value);\n});\n```\n\n\u003cbr\u003e\n\n#### Caching:\n```dart\nvar bmi = Telescope.dependsOnAsync(0, [height, weight], () async {\n   return await calculateBMI(height.value, weight.value);\n}, enableCaching: true);\n```\nYou can also set expire time by passing \u003cb\u003ecacheExpireTime\u003c/b\u003e.\n\n\u003cbr\u003e\n\n#### Debounce:\ndebounceTime: will call your async function only if a given time has passed without any changes on dependencies.\u003cbr\u003e\n```dart\nvar bmi = Telescope.dependsOnAsync(0, [height, weight], () async {\n   return await calculateBMI(height.value, weight.value);\n}, debounceTime: Duration(milliseconds: 500));\n```\nIt's useful when you want to run your async function when user stop typing or moving slider or...\n\n\n\u003cbr\u003e\n\n#### Observable on loading state:\nThis will make \u003cb\u003eisCalculatingBMI\u003c/b\u003e true on loading and false when loaded, you may need this to show loading animation.\n```dart\nvar isCalculatingBMI = Telescope\u003cbool\u003e(false);\nvar bmi = Telescope.dependsOnAsync(0, [height, weight], () async {\n   return await calculateBMI(height.value, weight.value);\n}, isCalculating: isCalculatingBMI);\n```\n\n\n### Save On Disk\nYou can save telescope data on disk easily like this:\n```dart\nvar height = Telescope.saveOnDiskForBuiltInType(187, \"bmi_height_input\");\n```\nSo if user close the app and open it again it will load last value of telescope for You.\n\u003cbr\u003e\n\n### TelescopeList\nTelescope implementation for list\n   * can be dependent\n   * can save on disk\n```dart\nvar items = TelescopeList([\"ab\", \"abb\", \"bc\", \"bcc\" , \"c\"]);\n```\n\n### Save non built in values on disk\nYou need to implement OnDiskSaveAbility for your object:\u003cbr\u003e\nFor example you have Human class:\n```dart\nclass Human{\n   int height;\n   int weight;\n   Human(this.height,this.weight);\n\n   @override\n   int get hashCode =\u003e height*weight;\n}\n```\nThen you need to make other class like this for Human:\n```dart\nclass HumanOnDiskAbility implements OnDiskSaveAbility\u003cHuman\u003e{\n   @override\n   Human parseOnDiskString(String data) {\n      var sp = data.split(\":\");\n      return Human(int.parse(sp[0]), int.parse(sp[1]));\n   }\n\n   @override\n   String toOnDiskString(Human instance) =\u003e \"${instance.height}:${instance.weight}\";\n}\n```\n\nAnd pass instance of HumanOnDiskAbility to Telescope:\n```dart\nvar human = Telescope.saveOnDiskForNonBuiltInType(\n        Human(187, 72),\n        \"human_for_bmi\",\n        HumanOnDiskAbility()\n);\n```\nTelescope will use 'parseOnDiskString' and 'toOnDiskString' to serialize and deserialize your object.\n\u003cbr\u003e\u003cbr\u003e\n\nThis method also can use in TelescopeList in same way.\n\n# Last Words:\n   * Plz:pray: star:star: repo.\n   * [Full documentation](https://pub.dev/documentation/telescope/latest/telescope/telescope-library.html).\n   * [Examples](https://github.com/ali77gh/Telescope/tree/master/example/lib).\n   * Static instance of Telescopes? \n     * it's not recommend because it decreases re-usability of your code, but in some use-cases it's OK to do that.\n   * Extends from Telescope?\n     * Why not? TelescopeList actually extends from Telescope\n   * Under MIT license \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fali77gh%2Ftelescope","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fali77gh%2Ftelescope","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fali77gh%2Ftelescope/lists"}