{"id":23512763,"url":"https://github.com/baethon/promise-duck","last_synced_at":"2026-07-18T08:31:00.787Z","repository":{"id":102098375,"uuid":"116557471","full_name":"baethon/promise-duck","owner":"baethon","description":"If it `then()` like a promise it is a promise.","archived":false,"fork":false,"pushed_at":"2018-01-10T10:55:57.000Z","size":28,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-10-30T00:55:02.237Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/baethon.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,"zenodo":null}},"created_at":"2018-01-07T10:48:30.000Z","updated_at":"2018-03-13T15:39:51.000Z","dependencies_parsed_at":"2023-06-03T13:20:54.896Z","dependency_job_id":null,"html_url":"https://github.com/baethon/promise-duck","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/baethon/promise-duck","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baethon%2Fpromise-duck","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baethon%2Fpromise-duck/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baethon%2Fpromise-duck/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baethon%2Fpromise-duck/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/baethon","download_url":"https://codeload.github.com/baethon/promise-duck/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baethon%2Fpromise-duck/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35612560,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-18T02:00:07.223Z","response_time":61,"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-12-25T13:19:23.479Z","updated_at":"2026-07-18T08:31:00.781Z","avatar_url":"https://github.com/baethon.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# promise-duck\n\nConverts given callback to `Thenable` object.  \nSuch object is compatible with Promise spec so it can be used as it was a real Promise.\n\nThe difference is that computation is *deferred* until `then()` method is called or `await` keyword is used.  \nIt's quite fair to say that in the way *how* it works such Promise is quite similar to [Task](https://github.com/folktale/data.task)\n\n\u003c!-- TOC depthFrom:2 depthTo:2 --\u003e\n\n- [why?](#why)\n- [installation](#installation)\n- [usage](#usage)\n- [development](#development)\n\n\u003c!-- /TOC --\u003e\n\n## why?\n\nThe idea came from little support library which was responsible for building a query (using sort-of fluent API) which was responsible for checking if given value is unique in the database.\n\nI was wondering if object with `then()` method can be used as a regular Promise. Turned out that its possible. \n\nThis little discovery opened me a way to define friendly syntax:\n\n```js\nconst emailUnique = await isUnique.in('users').where({ email: 'jon@winterfell.com' })\n```\n\nThe defined object can be stored in a variable and none query will be executed until calling `then()` or using `await` keyword.\n\n```js\n// define details of query (no query is executed!)\nconst query = isUnique.in('users').where({ email: 'jon@winterfell.com' })\n\n// query the database and return the results\nconst emailUnique = await query\n```\n\n## installation\n\n```\nnpm i @baethon/promise-duck\n\n# or with yarn\nyarn add @baethon/promise-duck\n```\n\n## usage\n\nPackage exposes two functions:\n\n1. `thenable()` converts given function to `Thenable` object.\n1. `bind()` converts given function and binds it to the selected object\n\n### thenable()\n\n```js\nconst { thenable } = require('@baethon/promise-duck')\n\nconst heavyStuff = Math.random\nconst p = thenable(heavyStuff)\n\nconst result = await p\n```\n\n### bind()\n\n```js\nconst { bind } = require('@baethon/promise-duck')\n\nconst heavyStuff = function () {\n  return `Hello ${this.name}`\n}\n\nconst object = { name: 'Jon' }\n\nbind(heavyStuff).to(object)\n\nconst result = await object\n```\n\n### results cache\n\nBy default results generated by given function will be cached.\n\nBoth, `thenable()` and `bind()` allow to disable cache by passing `memoize: false` option:\n\n```js\nconst { thenable } = require('@baethon/promise-duck')\n\nconst fn = Math.random\nconst p = thenable(fn, { memoize: false })\n```\n\n## development\n\nIf you're planning to contribute to the package please make sure to adhere to following conventions.\n\n### tests \u0026 linting\n\n* lint your code using [standard](https://standardjs.com/); run `npm run lint` to check if there are any linting errors\n* make sure to write tests for all the changes/bug fixes\n\n### issues \u0026 PR\n\n* try to provide regression test when you find a bug\n* share some context on what you are trying to do, with enough code to reproduce the issue\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbaethon%2Fpromise-duck","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbaethon%2Fpromise-duck","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbaethon%2Fpromise-duck/lists"}