{"id":15805424,"url":"https://github.com/jonaskello/effects-experiment","last_synced_at":"2025-08-31T20:33:10.122Z","repository":{"id":81765465,"uuid":"287278689","full_name":"jonaskello/effects-experiment","owner":"jonaskello","description":null,"archived":false,"fork":false,"pushed_at":"2020-08-24T13:24:18.000Z","size":116,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-08T04:20:52.683Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","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/jonaskello.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":"2020-08-13T12:50:44.000Z","updated_at":"2020-08-24T13:20:48.000Z","dependencies_parsed_at":"2023-03-12T14:01:30.719Z","dependency_job_id":null,"html_url":"https://github.com/jonaskello/effects-experiment","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jonaskello/effects-experiment","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonaskello%2Feffects-experiment","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonaskello%2Feffects-experiment/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonaskello%2Feffects-experiment/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonaskello%2Feffects-experiment/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jonaskello","download_url":"https://codeload.github.com/jonaskello/effects-experiment/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonaskello%2Feffects-experiment/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273034939,"owners_count":25034498,"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-08-31T02:00:09.071Z","response_time":79,"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":[],"created_at":"2024-10-05T02:20:44.097Z","updated_at":"2025-08-31T20:33:10.100Z","avatar_url":"https://github.com/jonaskello.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Effects Experiment\n\nExperiment with side-effects in typscript\n\n## Yieldable effect\n\nUses generators and the fact that `yield` in javascript is an expression that returns a value.\nEffects are encoded as data objects that describes the desired effect.\nThe function yields the effect descriptor objects and the infrastruture code responsible for executing the function turns the yielded effect descriptors into promises that it then awaits.\n\n### Pros\n\n- The effects the function can do is constrained to effects approved by the code that runs the function. It is very hard to cheat by doing an async effect in another way than yielding it.\n- Easy for the infrastructure code to run the function in steps (eg. for testing) with iterator.next().\n- Generators can be cancelled at any step but an async function cannot (minor advantage?).\n\n### Cons\n\n- Unfamiliar syntax to most developers.\n- Cannot infer the type of yield expression based on yielded value without workaround using `yield*`.\n- It is easy to cheat with an sync effect like `console.log()`.\n\n### Notes\n\nThis seems related to algebraic-effects\n\nhttps://github.com/phenax/algebraic-effects\nhttp://www.cse.chalmers.se/~rjmh/tfp/proceedings/TFP_2020_paper_10.pdf\n\nGenerator: infer the type of yield expression based on yielded value\n\nhttps://github.com/microsoft/TypeScript/issues/32523\n\nWork-around for infer the type of yield expression based on yielded value:\n\nhttps://github.com/microsoft/TypeScript/issues/36855#issuecomment-588286256\nhttps://www.typescriptlang.org/play?ssl=11\u0026ssc=2\u0026pln=1\u0026pc=1#code/PQKhFgCgAIWhjATgUwIYBdkGdqulgSwFsAHAG2WgHdFUSTlFoAzAVwDt50CB7d6dAAsM0ZOyysUOdAE8GWVM2SzofAYMoyCyMgBN86DMiJj0LHkzIEARrUTasAOiixoAZR7UN-GT1bU-PWhdTyweEyECdgBzaCsAa0oAA3g+LDMAD2gAXmgtHX0AN1QyJNx2fSFKWQZVZmgs3WQGCpw1YrJ8cORBHioAGjy-BFR+EJc4JKma7CQCEnQJgTlKAE1tPTcCWNyAHgAVAD4ACg6ALmh9gEpsw-3oYGB8bfZUSUoeevyg5AySKUIamYFiGkhGWGQzhgcFS4jM6wKOWgRFQiX2KwUSgRekYxwA3gBfXA4bG6LbRK4AbgmSzYnG4fDgv1QpAoxyueKW0G5DyeVEoITyG10cFG+gIZjEEiky3kimUMi5PNh6QaSO+IugpNOJSuSwJSymSSWAAESKhaERoCQJCEAMIlMjk17od7Qdg8MysCG6QZYXqsILWSjmrA+4nQJKEiPkspUDQodzbaAEaQaEZkTqEaIut2fdSaYWidjAxDwZD6awyUGWGx2GRQ2DAKB0ri8fgotEY+Wkxi7AAKiB4ulY5cGbjEuhONtY9sdzow7wuxxkF0Hw9HyCuOUO7kn285MB5rYZ7DgGtxFuia6HI-LVwuAHExIwMBYB7fN+PJ9+KrvDzygHQCgrqID4RZXtSR7cga0HAcokjgQUjBQbBMxakiBzTje4SpsgWHbrclxQSq8JIp2yDonKWLCri0aoCSVJQFA6EAKoQkwuR4imugXOk9gxJSuDRMgFzsKwRDBkwBJQU08BkBalAnu20Aieg7G4g+0DrkQeG7BpiCHFBLYcG2jLQN6jAAIIiey0AATyjwpiWjAoJUKwpjgqSICgXCNsqaRehx6rCnAqzHGpBnskxcEgYhFkcY4qAiahUBAA\n\n## Awaitable effect\n\nVery similar to Yieldable effect but uses the more familiar `await` syntax to do the effects.\nEffects are encoded as data objects that describes the desired effect.\nThe function gets passed a doEffects function that accepts an effect descriptor object and returns a Promise that can be awaited.\n\n### Pros\n\n- Familiar syntax to most developers.\n\n### Cons\n\n- You cannot constrain what an async function awaits. It is easy to cheat with an async effect, just call any API that returns Promise (eg. `fetch()`) and then await it.\n- You cannot run the function in steps (eg. for testing) unless you keep track of some state in the `doEffect` function.\n- It is easy to cheat with an sync effect like `console.log()`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonaskello%2Feffects-experiment","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjonaskello%2Feffects-experiment","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonaskello%2Feffects-experiment/lists"}