{"id":18003722,"url":"https://github.com/lowmelvin/mini-task","last_synced_at":"2025-04-04T09:41:23.004Z","repository":{"id":258814495,"uuid":"862956875","full_name":"lowmelvin/mini-task","owner":"lowmelvin","description":"Mini task graph for Scala 3","archived":false,"fork":false,"pushed_at":"2024-12-13T16:00:33.000Z","size":45,"stargazers_count":0,"open_issues_count":7,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-09T20:17:44.633Z","etag":null,"topics":["scala","scala3","task","task-graph"],"latest_commit_sha":null,"homepage":"","language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lowmelvin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2024-09-25T13:26:12.000Z","updated_at":"2024-12-13T16:00:38.000Z","dependencies_parsed_at":"2024-11-27T18:37:58.353Z","dependency_job_id":null,"html_url":"https://github.com/lowmelvin/mini-task","commit_stats":null,"previous_names":["lowmelvin/mini-task"],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lowmelvin%2Fmini-task","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lowmelvin%2Fmini-task/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lowmelvin%2Fmini-task/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lowmelvin%2Fmini-task/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lowmelvin","download_url":"https://codeload.github.com/lowmelvin/mini-task/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247157047,"owners_count":20893202,"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":["scala","scala3","task","task-graph"],"created_at":"2024-10-30T00:10:38.428Z","updated_at":"2025-04-04T09:41:22.976Z","avatar_url":"https://github.com/lowmelvin.png","language":"Scala","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Mini Task\n\n_Mini Task_ is a lightweight task graph library for Scala 3,\ndesigned for declaring and executing tasks with dependencies in a\ntype-safe and concurrent manner.\n\nMain features:\n\n- _Type-safe task dependencies_: The compiler ensures that the number and types of dependencies match the inputs of the provided task function.\n- _Concurrent execution_: Tasks are run concurrently whenever possible.\n- _Conditional execution_: Tasks can be conditionally executed based on the input values.\n- _Caching_: Intermediate results are automatically cached so each task is executed only once per run.\n\n## Installation\n\nThis library is built for Scala 3.\n\n```scala\nlibraryDependencies += \"com.melvinlow\" %% \"mini-task\" % \"\u003cVERSION\u003e\"\n```\n\n## Example\n\n\nCalculate `(1 + 2) * (3 + 4)`:\n\n```scala\nimport com.melvinlow.task.Task\n\nval a = Task.pure[IO](1)\nval b = Task.pure[IO](2)\nval c = Task.pure[IO](3)\nval d = Task.pure[IO](4)\n\n// Define tasks for addition\nval sum1 = Task.pure[IO]((a, b))(_ + _)  // 1 + 2\nval sum2 = Task.pure[IO]((c, d))(_ + _)  // 3 + 4\n\n// Define a task for multiplication\nval product = Task.pure[IO]((sum1, sum2))(_ * _)  // (1 + 2) * (3 + 4)\n```\n\nTo execute the task graph:\n\n```scala\nproduct.parRun(shards = 1).unsafeRunSync()\n// res0: Option[Int] = Some(value = 21)\n```\n\n## Conditional Execution\n\nEach task takes a `PartialFunction` that determines whether the task should be executed based on the input values.\nIf a task is not executed, all downstream tasks that depend on it will also not be executed.\n\nIn the following example, `k` will not be executed because it depends on `j`, which will only run if `i \u003e 10`:\n\n```scala\nval i = Task.pure[IO](1)\n\nval j = Task.pure[IO](i) {\n  case i if i \u003e 10 =\u003e i + 1 // only execute if i \u003e 10\n}\n\nval k = Task.pure[IO](j)(_ + 1)\n```\n\n```scala\nk.parRun(shards = 1).unsafeRunSync() // result of k is empty\n// res1: Option[Int] = None\n```\n\n## Effects\n\nThe compiler can infer the effect type when using tasks with effectful functions. Some syntax examples:\n\n```scala\nval x = Task(IO(1)) // 1\nval y = Task(x)(v =\u003e IO(v + 1)) // 1 + 1\nval z = Task((y, y))((v1, v2) =\u003e IO(v1 + v2)) // (1 + 1) + (1 + 1)\n```\n\n```scala\nz.parRun(shards = 1).unsafeRunSync()\n// res2: Option[Int] = Some(value = 4)\n```\n\n## Type Safety\n\nAll tasks are type-checked at compile time to ensure that\nthe number and types of dependencies match the inputs of the provided task function.\n\nThe following code does not compile because the order of the dependencies does not match the order of the inputs:\n\n```scala\nval strTask = Task.pure[IO](\"hello\")\nval intTask = Task.pure[IO](1)\n\n// swap the order of the tasks\nTask.pure[IO]((intTask, strTask)) { (s, i) =\u003e\n  s.length + \" \" + i\n}\n// error:\n// value length is not a member of Int\n//   s.length + \" \" + i\n//   ^^^^^^^^\n```\n\nThe following code does not compile because the number of inputs is wrong:\n\n```scala\nval intTask = Task.pure[IO](1)\n\n// Pass in 1 task instead of 2\nTask.pure[IO](intTask)(_ + _)\n// error:\n// Wrong number of parameters, expected: 1\n// Task.pure[IO](intTask)(_ + _)\n//                        ^^^^^\n```\n\n## Caching\n\nAll tasks will only be executed once per run, no matter how many times they are referenced.\n\n```scala\nvar counter = 0 // Don't try this at home\n\nval inc = Task(IO {\n  counter += 1\n  counter\n})\n```\n\n```scala\n// Create a task that calls inc 3 times\nTask((inc, inc, inc))(_.pure[IO]).run.unsafeRunSync()\n// res5: Option[Tuple3[Int, Int, Int]] = Some(value = (1, 1, 1))\n\n// counter is only incremented once\ncounter\n// res6: Int = 1\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flowmelvin%2Fmini-task","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flowmelvin%2Fmini-task","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flowmelvin%2Fmini-task/lists"}