{"_id":"@bemedev/better-promise","_rev":"2-ef23b0dee92d63800c4a53070013c3ec","name":"@bemedev/better-promise","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@bemedev/better-promise","version":"0.1.0","keywords":["promise","timeout","race","any","promisify","asyncify","abort","typescript","utils"],"author":{"url":"https://bemedev.vercel.app","name":"chlbri","email":"bri_lvi@icloud.com"},"license":"MIT","_id":"@bemedev/better-promise@0.1.0","maintainers":[{"name":"bemedev","email":"bri_lvi@icloud.com"}],"contributors":[{"url":"https://bemedev.vercel.app","name":"chlbri","email":"bri_lvi@icloud.com"}],"homepage":"https://github.com/chlbri/better-promise#readme","bugs":{"url":"https://github.com/chlbri/better-promise/issues"},"dist":{"shasum":"e2a921c36616dbc47afe3084a683483c99d6284f","tarball":"https://registry.npmjs.org/@bemedev/better-promise/-/better-promise-0.1.0.tgz","fileCount":47,"integrity":"sha512-DT5WAdw7LeB/HetRaaT6qrAC2kSu3MVtQaDdqIUWdY/SGXyJcvwjO++CRAhh8IuNWKfdB+iuZ90aC8bpqlKTug==","signatures":[{"sig":"MEUCIGuKDDMgGDtyi8sVmuTZDqHvbAC4Idc/gLMutkqXAI0lAiEAlrJ3o3Id7/4eDMbANTbDcLH6qw1QRARE9JXJ/hZUQco=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":40172},"main":"lib/index.js","type":"module","types":"lib/index.d.ts","module":"lib/index.js","engines":{"node":">=24"},"gitHead":"200ce467428c5534045d66433f3acc8cffdab5aa","scripts":{"ci":"CI_START=$(date +%s) && pnpm run config:off && pnpm run lint && pnpm run test && echo \"\n✅ CI takes $(($(date +%s) - CI_START))s\n\"","rm":"pnpx rimraf ./node_modules ./pnpm-lock.yaml","fmt":"oxfmt","p-q":"pretty-quick","lint":"pnpm run fmt && pnpm run lint:fix","size":"size-limit","test":"pnpm run test:coverage","_lint":"oxlint","build":"pnpm run rm:lib && pnpm run rolldown","rinit":"pnpm run rm && pnpm run config","config":"pnpm install","rm:lib":"pnpx rimraf ./lib","prepare":"husky","pretest":"pnpm run build && pnpm build-tests pre && pnpm run size","test:ui":"pnpm run pretest && vitest --ui","upgrade":"pnpm dlx @bemedev/upgrade-npm-package && pnpm run config:vitest","ci:admin":"pnpm run rm && pnpm run upgrade:fast && pnpm run ci","lint:fix":"oxlint --fix","posttest":"pnpm build-tests post && pnpm run fmt","rolldown":"rolldown -c","fmt:check":"oxfmt --check","rinit:off":"pnpm run rm && pnpm run config:off","test:only":"pnpm run test:coverage --no-coverage","config:off":"pnpm run config --offline","lint:watch":"onchange --await-write-finish 1500 -d 10000 -v \"**/*.ts\" -- pnpm run lint","test:watch":"vitest","build:watch":"onchange --await-write-finish 1500 -d 10000 -v \"**/*.ts\" -- pnpm run build","upgrade:fast":"pnpm up --latest && pnpm run config:vitest","config:vitest":"pnpm add -D @vitest/coverage-v8@3.2.4 @vitest/ui@3.2.4 vitest@3.2.4","test:coverage":"vitest run","prepublishOnly":""},"_npmUser":{"name":"bemedev","email":"bri_lvi@icloud.com"},"repository":{"url":"git+https://github.com/chlbri/better-promise.git","type":"git"},"size-limit":[{"path":"lib/*.js","limit":"10 KB"},{"path":"lib/*.cjs","limit":"10 KB"}],"_npmVersion":"11.11.0","description":"Promise utilities with timeout control, race helpers, and strong typing — withTimeout, racePromises, anyPromises, asyncfy, typedPromisify.","directories":{},"_nodeVersion":"24.14.1","_hasShrinkwrap":false,"devDependencies":{"glob":"^13.0.6","husky":"^9.1.7","oxfmt":"^0.43.0","tslib":"^2.8.1","oxlint":"^1.58.0","vitest":"^3.2.4","globals":"^17.4.0","onchange":"^7.1.0","prettier":"^3.8.1","rolldown":"1.0.0-rc.13","@vitest/ui":"3.2.4","size-limit":"^12.0.1","typescript":"^6.0.2","@types/node":"^25.5.2","pretty-quick":"^4.2.2","@bemedev/sleep":"^0.2.2","@size-limit/file":"^12.0.1","@bemedev/dev-utils":"^0.5.2","@vitest/coverage-v8":"^3.2.4","@bemedev/build-tests":"^0.1.2"},"_npmOperationalInternal":{"tmp":"tmp/better-promise_0.1.0_1775487972984_0.20312998884445088","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@bemedev/better-promise","version":"0.1.1","description":"Promise utilities with timeout control, race helpers, and strong typing — withTimeout, racePromises, anyPromises, asyncfy, typedPromisify.","author":{"name":"chlbri","email":"bri_lvi@icloud.com","url":"https://bemedev.vercel.app"},"repository":{"type":"git","url":"git+https://github.com/chlbri/better-promise.git"},"license":"MIT","type":"module","main":"lib/index.js","types":"lib/index.d.ts","module":"lib/index.js","maintainers":[{"name":"bemedev","email":"bri_lvi@icloud.com"}],"contributors":[{"name":"chlbri","email":"bri_lvi@icloud.com","url":"https://bemedev.vercel.app"}],"keywords":["promise","timeout","race","any","promisify","asyncify","abort","typescript","utils"],"engines":{"node":">=24"},"scripts":{"build":"pnpm run rm:lib && pnpm run rolldown","ci":"CI_START=$(date +%s) && pnpm run config:off && pnpm run lint && pnpm run test && echo \"\n✅ CI takes $(($(date +%s) - CI_START))s\n\"","ci:admin":"pnpm run rm && pnpm run upgrade:fast && pnpm run ci","config":"pnpm install","config:off":"pnpm run config --offline","config:vitest":"pnpm add -D @vitest/coverage-v8@3.2.4 @vitest/ui@3.2.4 vitest@3.2.4","_lint":"oxlint","lint:fix":"oxlint --fix","lint":"pnpm run fmt && pnpm run lint:fix","lint:watch":"onchange --await-write-finish 1500 -d 10000 -v \"**/*.ts\" -- pnpm run lint","build:watch":"onchange --await-write-finish 1500 -d 10000 -v \"**/*.ts\" -- pnpm run build","p-q":"pretty-quick","posttest":"pnpm build-tests post && pnpm run fmt","prepare":"husky","prepublishOnly":"","pretest":"pnpm run build && pnpm build-tests pre && pnpm run size","fmt":"oxfmt","fmt:check":"oxfmt --check","rinit":"pnpm run rm && pnpm run config","rinit:off":"pnpm run rm && pnpm run config:off","rm":"pnpx rimraf ./node_modules ./pnpm-lock.yaml","rm:lib":"pnpx rimraf ./lib","rolldown":"rolldown -c","test:coverage":"vitest run","test":"pnpm run test:coverage","test:only":"pnpm run test:coverage --no-coverage","test:ui":"pnpm run pretest && vitest --ui","test:watch":"vitest","upgrade":"pnpm dlx @bemedev/upgrade-npm-package && pnpm run config:vitest","size":"size-limit","upgrade:fast":"pnpm up --latest && pnpm run config:vitest"},"size-limit":[{"path":"lib/*.js","limit":"10 KB"},{"path":"lib/*.cjs","limit":"10 KB"}],"devDependencies":{"@bemedev/build-tests":"^0.1.2","@bemedev/dev-utils":"^0.5.2","@bemedev/sleep":"^0.2.2","@size-limit/file":"^12.0.1","@types/node":"^25.5.2","@vitest/coverage-v8":"^3.2.4","@vitest/ui":"3.2.4","glob":"^13.0.6","globals":"^17.4.0","husky":"^9.1.7","onchange":"^7.1.0","oxfmt":"^0.43.0","oxlint":"^1.58.0","prettier":"^3.8.1","pretty-quick":"^4.2.2","rolldown":"1.0.0-rc.13","size-limit":"^12.0.1","tslib":"^2.8.1","typescript":"^6.0.2","vitest":"^3.2.4"},"gitHead":"91143c5de40edd5a34d4fc5ea6626cdb27932988","_id":"@bemedev/better-promise@0.1.1","bugs":{"url":"https://github.com/chlbri/better-promise/issues"},"homepage":"https://github.com/chlbri/better-promise#readme","_nodeVersion":"24.14.1","_npmVersion":"11.11.0","dist":{"integrity":"sha512-+4i7ktfladsdRMOcri4K28iqzKzbkrRpbMQlqUa6XGhdTBZj0prv2dPD5NB91406Cj7Nml04OHdt9IMe0BUxrA==","shasum":"acf1758221cad69e9a81afd8b609c302fb131d55","tarball":"https://registry.npmjs.org/@bemedev/better-promise/-/better-promise-0.1.1.tgz","fileCount":47,"unpackedSize":40726,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIAbM3k8xPhzb4kbN9XQdclKdeXFJ8ZQlSXs8y/f3kGfJAiEAsIvjcpvsdPEb93S8MPapeTmV8iViXSKSqQag5mQgl/g="}]},"_npmUser":{"name":"bemedev","email":"bri_lvi@icloud.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/better-promise_0.1.1_1775516858774_0.7736181060908767"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-06T15:06:12.834Z","modified":"2026-04-06T23:07:39.028Z","0.1.0":"2026-04-06T15:06:13.142Z","0.1.1":"2026-04-06T23:07:38.922Z"},"bugs":{"url":"https://github.com/chlbri/better-promise/issues"},"author":{"name":"chlbri","email":"bri_lvi@icloud.com","url":"https://bemedev.vercel.app"},"license":"MIT","homepage":"https://github.com/chlbri/better-promise#readme","keywords":["promise","timeout","race","any","promisify","asyncify","abort","typescript","utils"],"repository":{"type":"git","url":"git+https://github.com/chlbri/better-promise.git"},"description":"Promise utilities with timeout control, race helpers, and strong typing — withTimeout, racePromises, anyPromises, asyncfy, typedPromisify.","contributors":[{"name":"chlbri","email":"bri_lvi@icloud.com","url":"https://bemedev.vercel.app"}],"maintainers":[{"name":"bemedev","email":"bri_lvi@icloud.com"}],"readme":"# @bemedev/better-promise\n\nPromise utilities with timeout control, race helpers, and strong typing.\n\n<br/>\n\n## Installation\n\n```sh\npnpm add @bemedev/better-promise\n```\n\n## API\n\n### `withTimeout(promise, id, ...timeouts)`\n\nWraps a promise with one or more timeout deadlines. Rejects with a message\nlike `\"Timed out after 500 ms.\"` if the promise does not settle in time.\nAutomatically clears all timers on settlement.\n\n```ts\nimport { withTimeout } from '@bemedev/better-promise';\n\nconst wrapped = withTimeout(\n  () => fetch('/api/data').then(r => r.json()),\n  'fetch-data',\n  3000, // reject after 3 s\n);\n\nconst result = await wrapped();\n\n// Cancel at any time\nwrapped.abort();\n```\n\n#### `withTimeout.safe(promise, id, ...timeouts)`\n\nSame as `withTimeout` but resolves to `undefined` instead of rejecting on\ntimeout or abort.\n\n---\n\n### `racePromises(id, ...promises)`\n\nRaces multiple `TimeoutPromise`s using `Promise.race`. The first to settle\nwins; all others are aborted.\n\n```ts\nimport { racePromises, withTimeout } from '@bemedev/better-promise';\n\nconst a = withTimeout(() => fetchA(), 'a', 1000);\nconst b = withTimeout(() => fetchB(), 'b', 1000);\n\nconst winner = racePromises('race-ab', a, b);\nconst result = await winner();\n```\n\n---\n\n### `anyPromises(id, ...promises)`\n\nRaces multiple `TimeoutPromise`s using `Promise.any`. Resolves with the\nfirst fulfillment; rejects only when all have rejected.\n\n```ts\nimport { anyPromises, withTimeout } from '@bemedev/better-promise';\n\nconst a = withTimeout(() => fetchA(), 'a', 1000);\nconst b = withTimeout(() => fetchB(), 'b', 1000);\n\nconst first = anyPromises('any-ab', a, b);\nconst result = await first();\n```\n\n---\n\n### `asyncfy(fn)`\n\nWraps a synchronous function so it returns a `Promise`.\n\n```ts\nimport { asyncfy } from '@bemedev/better-promise';\n\nconst asyncAdd = asyncfy((a: number, b: number) => a + b);\nconst result = await asyncAdd(1, 2); // 3\n```\n\n---\n\n### `typedPromisify(fn)`\n\nConverts a Node.js-style callback function `(…args, cb)` into a\npromise-returning function, fully typed.\n\n```ts\nimport { typedPromisify } from '@bemedev/better-promise';\nimport fs from 'node:fs';\n\nconst readFile = typedPromisify(fs.readFile);\nconst content = await readFile('./file.txt', 'utf8');\n```\n\n---\n\n## Types\n\n| Type                    | Description                                                  |\n| ----------------------- | ------------------------------------------------------------ |\n| `TimeoutPromise<T>`     | Callable promise with `.abort()` and `.id` properties        |\n| `TypeFromTimeout<T>`    | Extracts the resolved type from a `TimeoutPromise<T>`        |\n| `TypeFromTimeouts<T>`   | Extracts the union of resolved types from `TimeoutPromise[]` |\n| `Fn<Args, R>`           | Generic function type                                        |\n| `FnBasic<Main, Tr>`     | Intersection of a function type and an object type           |\n| `Callback`              | Node-style callback — `(err, result?)` or `(err)`            |\n| `CallBackError`         | Callback with error only — `(err: any) => void`              |\n| `CallBackResult<T>`     | Callback with error and result — `(err: any, result: T)`     |\n| `CbParams`              | Tuple of `[...args, Callback]`                               |\n| `ResultFrom<T>`         | Infers the promise-returning signature from `CbParams`       |\n\n<br/>\n\n## Licence\n\nMIT\n\n## CHANGELOG\n\nRead [CHANGELOG.md](CHANGELOG.md) for more details about the changes.\n\n<br/>\n\n## Auteur\n\nchlbri (bri_lvi@icloud.com)\n\n[My github](https://github.com/chlbri?tab=repositories)\n\n[<svg width=\"98\" height=\"96\" xmlns=\"http://www.w3.org/2000/svg\"><path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z\" fill=\"#24292f\"/></svg>](https://github.com/chlbri?tab=repositories)\n\n<br/>\n\n## Liens\n\n- [Documentation](https://github.com/chlbri/new-package)\n","readmeFilename":"README.md"}