{"_id":"stubborn-utils","_rev":"4106793","name":"stubborn-utils","description":"A small collection of utilities for making functions somewhat resilient against errors.","dist-tags":{"latest":"1.0.2"},"maintainers":[{"name":"fabiospampinato","email":"spampinabio@gmail.com"}],"time":{"modified":"2026-01-11T18:56:36.000Z","created":"2025-10-26T19:07:04.595Z","1.0.2":"2025-11-01T13:27:10.071Z","1.0.1":"2025-10-26T19:32:59.239Z","1.0.0":"2025-10-26T19:07:04.595Z"},"users":{},"repository":{"type":"git","url":"git+https://github.com/fabiospampinato/stubborn-utils.git"},"versions":{"1.0.2":{"name":"stubborn-utils","repository":{"type":"git","url":"git+https://github.com/fabiospampinato/stubborn-utils.git"},"description":"A small collection of utilities for making functions somewhat resilient against errors.","license":"MIT","version":"1.0.2","type":"module","main":"dist/index.js","exports":"./dist/index.js","types":"./dist/index.d.ts","scripts":{"clean":"tsex clean","compile":"tsex compile","compile:watch":"tsex compile --watch","test":"tsex test","test:watch":"tsex test --watch","prepublishOnly":"tsex prepare"},"keywords":["stubborn","collection","utilities","functions"],"devDependencies":{"fava":"^0.3.5","tsex":"^4.0.2","typescript":"^5.9.3"},"_id":"stubborn-utils@1.0.2","gitHead":"7022991ae262c1fbb54f19171ee7d0a5303e6a46","bugs":{"url":"https://github.com/fabiospampinato/stubborn-utils/issues"},"homepage":"https://github.com/fabiospampinato/stubborn-utils#readme","_nodeVersion":"18.19.0","_npmVersion":"10.2.3","dist":{"shasum":"0d9c58ab550f40936235056c7ea6febd925c4d41","size":3337,"noattachment":false,"key":"/stubborn-utils/-/stubborn-utils-1.0.2.tgz","tarball":"http://registry.cnpm.dingdandao.com/stubborn-utils/download/stubborn-utils-1.0.2.tgz"},"_npmUser":{"name":"fabiospampinato","email":"spampinabio@gmail.com"},"directories":{},"maintainers":[{"name":"fabiospampinato","email":"spampinabio@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/stubborn-utils_1.0.2_1762003629867_0.35641481511344697"},"_hasShrinkwrap":false,"_cnpmcore_publish_time":"2025-11-01T13:27:10.071Z","publish_time":1762003630071,"_source_registry_name":"default","_cnpm_publish_time":1762003630071},"1.0.1":{"name":"stubborn-utils","repository":{"type":"git","url":"git+https://github.com/fabiospampinato/stubborn-utils.git"},"description":"A small collection of utilities for making functions somewhat resilient against errors.","version":"1.0.1","type":"module","main":"dist/index.js","exports":"./dist/index.js","types":"./dist/index.d.ts","scripts":{"clean":"tsex clean","compile":"tsex compile","compile:watch":"tsex compile --watch","test":"tsex test","test:watch":"tsex test --watch","prepublishOnly":"tsex prepare"},"keywords":["stubborn","collection","utilities","functions"],"devDependencies":{"fava":"^0.3.5","tsex":"^4.0.2","typescript":"^5.9.3"},"_id":"stubborn-utils@1.0.1","gitHead":"7d92f526a0c6561d9e5d04fc8e385e47d86440d3","bugs":{"url":"https://github.com/fabiospampinato/stubborn-utils/issues"},"homepage":"https://github.com/fabiospampinato/stubborn-utils#readme","_nodeVersion":"18.19.0","_npmVersion":"10.2.3","dist":{"shasum":"e6e8feafddc255b55b08df373c98ea50310e3798","size":3329,"noattachment":false,"key":"/stubborn-utils/-/stubborn-utils-1.0.1.tgz","tarball":"http://registry.cnpm.dingdandao.com/stubborn-utils/download/stubborn-utils-1.0.1.tgz"},"_npmUser":{"name":"fabiospampinato","email":"spampinabio@gmail.com"},"directories":{},"maintainers":[{"name":"fabiospampinato","email":"spampinabio@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/stubborn-utils_1.0.1_1761507179052_0.1097487248836364"},"_hasShrinkwrap":false,"_cnpmcore_publish_time":"2025-10-26T19:32:59.239Z","publish_time":1761507179239,"_source_registry_name":"default","_cnpm_publish_time":1761507179239},"1.0.0":{"name":"stubborn-utils","repository":{"type":"git","url":"git+https://github.com/fabiospampinato/stubborn-utils.git"},"description":"A small collection of utilities for making functions somewhat resilient against errors.","version":"1.0.0","type":"module","main":"dist/index.js","exports":"./dist/index.js","types":"./dist/index.d.ts","scripts":{"clean":"tsex clean","compile":"tsex compile","compile:watch":"tsex compile --watch","test":"tsex test","test:watch":"tsex test --watch","prepublishOnly":"tsex prepare"},"keywords":["stubborn","collection","utilities","functions"],"devDependencies":{"fava":"^0.3.5","tsex":"^4.0.2","typescript":"^5.9.3"},"_id":"stubborn-utils@1.0.0","bugs":{"url":"https://github.com/fabiospampinato/stubborn-utils/issues"},"homepage":"https://github.com/fabiospampinato/stubborn-utils#readme","_nodeVersion":"18.19.0","_npmVersion":"10.2.3","dist":{"shasum":"e2e32c3fab8a2dcb2465a111d15025e980338e24","size":3334,"noattachment":false,"key":"/stubborn-utils/-/stubborn-utils-1.0.0.tgz","tarball":"http://registry.cnpm.dingdandao.com/stubborn-utils/download/stubborn-utils-1.0.0.tgz"},"_npmUser":{"name":"fabiospampinato","email":"spampinabio@gmail.com"},"directories":{},"maintainers":[{"name":"fabiospampinato","email":"spampinabio@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/stubborn-utils_1.0.0_1761505624388_0.2525462865895616"},"_hasShrinkwrap":false,"_cnpmcore_publish_time":"2025-10-26T19:07:04.595Z","publish_time":1761505624595,"_source_registry_name":"default","_cnpm_publish_time":1761505624595}},"readme":"# Stubborn Utils\n\nA small collection of utilities for making functions somewhat resilient against errors.\n\n## Install\n\n```sh\nnpm install stubborn-utils\n```\n\n## Usage\n\n#### `attemptifyAsync`\n\nThis function wraps an async function, and in case this wrapped function rejects then the error is automatically caught by the `onError` callback.\n\n```ts\nimport {attemptifyAsync} from 'stubborn-utils';\n\n// Let's create a wrapped function\n\nconst asyncFunction = async () => {\n  await someAsyncThing ();\n  if ( Math.random () > 0.5 ) {\n    throw new Error ( 'Unlucky' );\n  } else {\n    return 123;\n  }\n};\n\nconst attemptifiedAsyncFunction = attemptifyAsync ( asyncFunction, {\n  onError: error => {\n    return -1;\n  }\n});\n\nconst result = attemptifiedAsyncFunction (); // => Promise<123 | -1>\n```\n\n#### `attemptifySync`\n\nThis function wraps a sync function, and in case this wrapped function throws then the error is automatically caught by the `onError` callback.\n\n```ts\nimport {attemptifySync} from 'stubborn-utils';\n\n// Let's create a wrapped function\n\nconst syncFunction = () => {\n  if ( Math.random () > 0.5 ) {\n    throw new Error ( 'Unlucky' );\n  } else {\n    return 123;\n  }\n};\n\nconst attemptifiedSyncFunction = attemptifySync ( syncFunction, {\n  onError: error => {\n    return -1;\n  }\n});\n\nconst result = attemptifiedSyncFunction (); // => 123 | -1\n```\n\n#### `retryifyAsync`\n\nThis function wraps an async function, and in case this wrapped function rejects then the `isRetriable` callback is called to decide if we should retry calling the function again.\n\nThere's also another layer of options before you can actually call the retryified function, that allows you to provide a maximum `timeout` for the retry loop, and an optional `interval` that should approximately pass between retries.\n\nBefore the function is retried again a random amount of milliseconds between `0` and `interval` will be waited for.\n\nBy default `interval` would be set to `250`.\n\n```ts\nimport {retryifyAsync} from 'stubborn-utils';\n\n// Let's create a wrapped function\n\nconst asyncFunction = async () => {\n  await someAsyncThing ();\n  if ( Math.random () > 0.5 ) {\n    throw new Error ( 'Unlucky' );\n  } else {\n    return 123;\n  }\n};\n\nconst retryifiedAsyncFunction = retryifyAsync ( asyncFunction, {\n  isRetriable: error => {\n    return true; // Always retriablein this scenario\n  }\n});\n\nconst result = retryifiedAsyncFunction ({\n  timeout: 1_000,\n  interval: 100\n}); // => Promise<123 | -1>, but Promise<123> with much higher probability\n```\n\n#### `retryifySync`\n\nThis function wraps a sync function, and in case this wrapped function throws then the `isRetriable` callback is called to decide if we should retry calling the function again.\n\nThere's also another layer of options before you can actually call the retryified function, that allows you to provide a maximum `timeout` for the retry loop, and an optional `interval` that should approximately pass between retries.\n\nBefore the function is retried again a random amount of milliseconds between `0` and `interval` will be waited for.\n\nBy default `interval` would be set to `250`.\n\n```ts\nimport {retryifySync} from 'stubborn-utils';\n\n// Let's create a wrapped function\n\nconst syncFunction = () => {\n  if ( Math.random () > 0.5 ) {\n    throw new Error ( 'Unlucky' );\n  } else {\n    return 123;\n  }\n};\n\nconst retryifiedSyncFunction = retryifySync ( syncFunction, {\n  isRetriable: error => {\n    return true; // Always retriablein this scenario\n  }\n});\n\nconst result = retryifiedSyncFunction ({\n  timeout: 1_000,\n  interval: 100\n}); // => 123 | -1, but 123 with much higher probability\n```\n\n## License\n\nMIT © Fabio Spampinato\n","_attachments":{},"homepage":"https://github.com/fabiospampinato/stubborn-utils#readme","bugs":{"url":"https://github.com/fabiospampinato/stubborn-utils/issues"},"license":"MIT"}