{"id":17736749,"url":"https://github.com/parro-it/ai-fun","last_synced_at":"2025-08-26T08:07:25.287Z","repository":{"id":66074121,"uuid":"111142932","full_name":"parro-it/ai-fun","owner":"parro-it","description":"A collection of modules to easy deal with async iterables","archived":false,"fork":false,"pushed_at":"2017-12-04T19:25:47.000Z","size":61,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-01T02:05:52.211Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Shell","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/parro-it.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}},"created_at":"2017-11-17T19:32:44.000Z","updated_at":"2019-07-08T22:03:47.000Z","dependencies_parsed_at":"2023-03-25T22:04:29.230Z","dependency_job_id":null,"html_url":"https://github.com/parro-it/ai-fun","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/parro-it/ai-fun","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/parro-it%2Fai-fun","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/parro-it%2Fai-fun/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/parro-it%2Fai-fun/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/parro-it%2Fai-fun/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/parro-it","download_url":"https://codeload.github.com/parro-it/ai-fun/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/parro-it%2Fai-fun/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272192669,"owners_count":24889452,"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-26T02:00:07.904Z","response_time":60,"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-26T00:24:17.736Z","updated_at":"2025-08-26T08:07:25.247Z","avatar_url":"https://github.com/parro-it.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ai-fun\n\nA collection of modules to easy deal with async iterables\n\n# Modules list\n\n* [ai-event](https://github.com/parro-it/ai-event#readme) - Create an async iterable from an event emitter.\n* [ai-node](https://github.com/parro-it/ai-node#readme) - Node wrappers that returns async iterables and promises.\n* [ai-asfullfills](https://github.com/parro-it/ai-asfullfills#readme) - Return an aync iterable that emit a series promises as they fullfills\n* [ai-merge](https://github.com/parro-it/ai-merge#readme) - Parallel merge of multiple async iterable.\n* [ai-filter](https://github.com/parro-it/ai-filter#readme) - Filter over async iterables.\n* [ai-lines](https://github.com/parro-it/ai-lines#readme) - Split an async iterable into lines.\n* [ai-map](https://github.com/parro-it/ai-map#readme) - Map over async iterables\n* [ai-sequence](https://github.com/parro-it/ai-sequence#readme) - Serial  merge of multiple async iterable.\n* [ai-concat](https://github.com/parro-it/ai-concat#readme) - Concat an async iterable into a promise\n* [ai-reduce](https://github.com/parro-it/ai-reduce#readme) - Reduce for async iterables.\n* [asynciterable](https://github.com/parro-it/asynciterable#readme) - Async iterable class\n* [ai-from-stream](https://github.com/parro-it/ai-from-stream#readme) - create an async iterable from a stream\n* [ai-log](https://github.com/parro-it/ai-log#readme) - Tap into an async iterable pipeline and log all chunks passing through\n* [ai-tap](https://github.com/parro-it/ai-tap#readme) - Tap into an async iterable chain without affecting its value or state.\n* [is-async-iterable](https://github.com/parro-it/is-async-iterable#readme) - Checks if a given object is async iterable.\n\n\n\n# Common conventions\n\nAll ai-fun modules follows a set of common conventions to improve interoperability within the modules.\n\n* _Currying_\n\nCurrying is a common functional tecnique made popular by early functional languages.\nIt allow to transform a function with arity \u003e 1 in a unary function, by partially applying a set of argument to the function:\n\n```js\ncurriedFunction(a)(b)(c) === curriedFunction(a, b, c)\n```\n\nThe advantage of using unary functions is that you can use it\nas arguments in higher order function:\n\n```js\nconst fetchUrl = curried((options, url) =\u003e {})\nconst docs = urlArr.map(fetchUrl({method: post}))\n```\n\nWithin the javascript community, currying was popularized by\nlibraries like [ramda](https://github.com/ramda/ramda), but as\n[explained by Dr. Axel Rauschmayer](http://2ality.com/2017/11/currying-in-js.html) with his consuete deepness, it has some\ndrawbacks.\n\nNormal currying has another characteritic that greatly\neffect async functions: if you return a function in a async function,\nthe caller get a promise of a function, making the caller site syntax\nugly:\n\n```\nconst fetchUrl = curried(async (options, url) =\u003e {})\nconst docs = urlArr.map(await fetchUrl({method: post}))\n```\n\nAnd things get worse if the function is an async generator:\n\n```\nconst fetchUrl = await curried(async function * (options, url) =\u003e {})\nconst docs = urlArr.map((await fetchUrl({method: post}).next()).value)\n```\n\n\nSo, ai-fun modules take a different approach: each function\nhas an `with` method that partially apply it's arguments to the main\nfunction, returning a unary function that accept the data\n(or context, or main) parameter.\n\nFor example, to transform the `reduce` function in unary\none:\n\n```js\nconst sum = reduce.with((acc, val) =\u003e acc + val, 0)\nconsole.log(await sum([1, 2 ,3]))\n// output 6\n```\n\n* _Versioning_\n\nAll `ai-fun` modules started with version 1 and follows [semantic versioning](https://semver.org/).\nAll major version bumping will happen at the same time for all of the modules.\n\n* _Iteration lazyness_\n\nfor await vs map -\u003e lower order iterables are iterated only when needed\n(optionally?)\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fparro-it%2Fai-fun","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fparro-it%2Fai-fun","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fparro-it%2Fai-fun/lists"}