{"id":16439154,"url":"https://github.com/posva/p-singleton","last_synced_at":"2025-06-23T17:34:05.148Z","repository":{"id":34272674,"uuid":"174035930","full_name":"posva/p-singleton","owner":"posva","description":"Ensure only one instance of a promise is created until rejected or resolved","archived":false,"fork":false,"pushed_at":"2024-11-22T17:45:27.000Z","size":698,"stargazers_count":19,"open_issues_count":4,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-12-27T15:46:23.705Z","etag":null,"topics":["async-functions","javascript","nodejs","promise","promise-modules","promises"],"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/posva.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":".github/funding.yml","license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","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},"funding":{"github":"posva"}},"created_at":"2019-03-05T23:24:32.000Z","updated_at":"2022-03-06T03:48:45.000Z","dependencies_parsed_at":"2023-01-15T06:00:42.118Z","dependency_job_id":"6222f209-542b-4ef6-9c57-def4bb3874e1","html_url":"https://github.com/posva/p-singleton","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/posva%2Fp-singleton","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/posva%2Fp-singleton/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/posva%2Fp-singleton/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/posva%2Fp-singleton/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/posva","download_url":"https://codeload.github.com/posva/p-singleton/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":232615200,"owners_count":18550648,"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":["async-functions","javascript","nodejs","promise","promise-modules","promises"],"created_at":"2024-10-11T09:08:13.647Z","updated_at":"2025-01-05T16:51:30.395Z","avatar_url":"https://github.com/posva.png","language":"JavaScript","funding_links":["https://github.com/sponsors/posva"],"categories":[],"sub_categories":[],"readme":"# p-singleton [![Build Status](https://badgen.net/circleci/github/posva/p-singleton)](https://circleci.com/gh/posva/p-singleton) [![npm package](https://badgen.net/npm/v/p-singleton)](https://www.npmjs.com/package/p-singleton) [![coverage](https://badgen.net/codecov/c/github/posva/p-singleton)](https://codecov.io/github/posva/p-singleton) [![thanks](https://badgen.net/badge/thanks/♥/pink)](https://github.com/posva/thanks)\n\n\u003e Ensure only one version of a Promise-returning function is running at a time\n\n## Installation\n\n```sh\nnpm install p-singleton\n```\n\n## Usage\n\n```js\nconst pSingleton = require('p-singleton')\n\n// any function that returns a promise\nfunction fetchUserDetailsAndDoSomething(id) {\n  return fetch('/api/users/' + id).then(res =\u003e res.json())\n}\n\nconst singletonUserFetch = pSingleton(fetchUserDetailsAndDoSomething)\n\nconst p1 = singletonUserFetch(2)\nconst p2 = singletonUserFetch(2)\nconst p3 = singletonUserFetch(3)\np1 === p2 // pointing to the same promise\np1 !== p3 // different promises because it was called with different arguments\n\n// wait for p1 to resolve\nawait p1\nconst p4 = singletonUserFetch(2)\np4 !== p1 // a new promise is created\n```\n\n`p-singleton` uses `JSON.stringify` to cache existing promises by using the arguments passed to the function call (`singletonUserFetch` in the example) as the key. Then it hops into its `finally` hook to remove the promise from the cache so a new one is created the next time the function is called.\nThis will work out well most of the times but if you need something more performant (specially when dealing with objects as arguments) you can provide your own implementation:\n\n```js\nconst singletonFetchUser = pSingleton(fetchData, ([user]) =\u003e user.id) // uses the id as the key\nsingletonFetchUser({ id: 1 })\n\nconst singletonFetchDocument = pSingleton(fetchData, ([user, options]) =\u003e `${user.id};${options.includeRefs}`) // uses multiple arguments\nsingletonFetchDocument({ id: 1 }),{ includeRefs: true })\n```\n\n## API\n\n### `pSingleton(fn: (...args: any[]) =\u003e Promise\u003cany\u003e, serializer?: (...args: any[]) =\u003e string)) =\u003e (...args: any[]) =\u003e Promise\u003cany\u003e`\n\n- `fn`: function that returns a Promise\n- `serializer`: optional serializer function, defaults to JSON.stringify\n\nreturns a function that returns a Promise\n\n## Related\n\n- [p-fun](https://github.com/sindresorhus/promise-fun)\n\n## License\n\n[MIT](http://opensource.org/licenses/MIT)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fposva%2Fp-singleton","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fposva%2Fp-singleton","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fposva%2Fp-singleton/lists"}