{"id":18974648,"url":"https://github.com/asd-xiv/m","last_synced_at":"2025-04-19T16:40:50.021Z","repository":{"id":38173117,"uuid":"101939680","full_name":"asd-xiv/m","owner":"asd-xiv","description":"Point free style, functional library for Javascript with focus on object arrays.","archived":false,"fork":false,"pushed_at":"2023-02-12T14:59:45.000Z","size":7552,"stargazers_count":4,"open_issues_count":9,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-11T16:40:10.832Z","etag":null,"topics":["functional","javascript","library","point-free"],"latest_commit_sha":null,"homepage":"https://asd-xiv.github.io/m/","language":"JavaScript","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/asd-xiv.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":"2017-08-30T23:58:19.000Z","updated_at":"2022-01-30T11:41:55.000Z","dependencies_parsed_at":"2023-02-18T13:01:10.469Z","dependency_job_id":null,"html_url":"https://github.com/asd-xiv/m","commit_stats":{"total_commits":546,"total_committers":5,"mean_commits":109.2,"dds":0.5934065934065934,"last_synced_commit":"51948ef9df6a4e655fc2c188b54a2e8d28de2005"},"previous_names":["andreidmt/m"],"tags_count":121,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asd-xiv%2Fm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asd-xiv%2Fm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asd-xiv%2Fm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asd-xiv%2Fm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/asd-xiv","download_url":"https://codeload.github.com/asd-xiv/m/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249223936,"owners_count":21232833,"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":["functional","javascript","library","point-free"],"created_at":"2024-11-08T15:15:40.603Z","updated_at":"2025-04-16T09:34:02.238Z","avatar_url":"https://github.com/asd-xiv.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!-- markdownlint-disable first-line-h1 line-length --\u003e\n\n[![CircleCI](https://circleci.com/gh/asd-xiv/m.svg?style=svg)](https://circleci.com/gh/asd-xiv/m)\n[![npm version](https://badge.fury.io/js/%40asd14%2Fm.svg)](https://badge.fury.io/js/%40asd14%2Fm)\n[![Coverage Status](https://coveralls.io/repos/github/asd-xiv/m/badge.svg)](https://coveralls.io/github/asd-xiv/m)\n\n# m\n\n\u003e [Point free](https://en.wikipedia.org/wiki/Tacit_programming) style,\n\u003e functional library for Javascript with focus on object arrays.\n\n---\n\n\u003c!-- vim-markdown-toc GFM --\u003e\n\n- [Install](#install)\n- [Use](#use)\n- [\"With\" pattern](#with-pattern)\n- [|\u003e pipe](#-pipe)\n- [Develop](#develop)\n- [Contributors](#contributors)\n- [Changelog](#changelog)\n\n\u003c!-- vim-markdown-toc --\u003e\n\n## Install\n\n```bash\nnpm install @asd14/m\n```\n\n## Use\n\n```js\nimport { pipe, trim, split, dropLast, push, join } from \"@asd14/m\"\n\nconst removeTrailingSlash = source =\u003e\n  source[source.length - 1] === sep ? source.slice(0, -1) : source\n\nconst renameFile = newName =\u003e\n  pipe(\n    removeTrailingSlash,\n    split(sep),\n    dropLast,\n    push(trim(sep, newName)),\n    join(sep)\n  )\n```\n\n## \"With\" pattern\n\nSome functions have a `*With` variant. `find` has `findWith`, `filter` has\n`filterWith` etc. They allow for less boilerplate and more intuitive way of\nhandling object arrays.\n\n```js\nimport { find, findWith, filterWith, not, is } from \"@asd14/m\"\n\nconst todos = [\n  { id: 1, name: \"lorem\", tagId: 2 },\n  { id: 2, name: \"ipsum\", tagId: null },\n  { id: 3, name: \"dolor\", tagId: null },\n]\n```\n\n```js\n/* Predicate fn */\nfind(item =\u003e item.id === 1, todos)\n// =\u003e {id: 1, name: \"lorem\", tagId: 2}\n\n/* Matching object */\nfindWith(\n  {\n    id: 1,\n  },\n  todos\n)\n// =\u003e {id: 1, name: \"lorem\", tagId: 2}\n\n/* Matching object \u0026 predicate fn */\nfilterWith(\n  {\n    tagId: is, // same as `tagId: source =\u003e is(source)`\n  },\n  todos\n)\n// =\u003e [{id: 1, name: \"lorem\", tagId: 2}]\n\n/* Syntactic sugar */\nfilterWith(\n  {\n    \"!tagId\": is, // same as `tagId: not(is)`\n  },\n  todos\n)\n// =\u003e [\n//  {id: 2, name: \"ipsum\", tagId: null},\n//  {id: 3, name: \"dolor\", tagId: null}\n// ]\n```\n\n## |\u003e pipe\n\nThere is no _structure_ difference between `pipe` and `compose`, both will use\nthe same building blocks to get from A to B.\n\nA series of transformations over an initial input can be written as\n`x -\u003e f -\u003e g -\u003e result`, _piping_, or as `result = g(f(x))`, _composing_. The\ndifference is only _syntactic_. Input is the same, transformations **and** order\nof application are the same, the result will be the same.\n\nGiven that:\n\n- we read from left to right\n- [left/back is in the past, right/front is the future](https://medium.com/@cwodtke/the-intuitive-and-the-unlearnable-cccffd9a762)\n- a lot of piping going on in your terminal\n\nit makes sense to choose the _syntax_ more aligned with our intuition and\ncontext. The transformations are applied in a certain order with time as a\nmedium - `input -\u003e t0 -\u003e t1 -\u003e tn -\u003e output`.\n\n```js\nconst { sep } = require(\"path\")\nconst { pipe, compose, join, push, dropLast, split } = require(\"@asd14/m\")\n\n// Compose: g(f(x))\nconst renameFile = newName =\u003e filePath =\u003e\n  compose(join(sep), push(newName), dropLast, split(sep))(filePath)\n\n// Pipe: x -\u003e f -\u003e g\nconst renameFile = newName =\u003e filePath =\u003e\n  pipe(split(sep), dropLast, push(newName), join(sep))(filePath)\n\n// More expressive with pipeline operator\nconst renameFile = newName =\u003e filePath =\u003e\n  filePath |\u003e split(sep) |\u003e dropLast |\u003e push(newName) |\u003e join(sep)\n```\n\n## Develop\n\n```bash\ngit clone git@github.com:asd14-xyz/m.git \u0026\u0026 \\\n  cd m \u0026\u0026 \\\n  npm run setup\n\n# run tests (any `*.test.js`) once\nnpm test\n\n# watch `src` folder for changes and run test automatically\nnpm run tdd\n```\n\n## Contributors\n\nThank you for contributing your time and knowledge:\n\n- [David Gil](https://github.com/dgilperez)\n\n## Changelog\n\nSee the [releases section](https://github.com/asd14-xyz/m/releases) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasd-xiv%2Fm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fasd-xiv%2Fm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasd-xiv%2Fm/lists"}