{"_id":"tryer","_rev":"196488","name":"tryer","description":"Because everyone loves a tryer! Conditional and repeated task invocation for node and browser.","dist-tags":{"latest":"1.0.1"},"maintainers":[{"name":"philbooth","email":"pmbooth@gmail.com"}],"time":{"modified":"2021-06-03T12:29:46.000Z","created":"2017-09-09T14:10:47.594Z","1.0.1":"2018-06-24T07:49:33.998Z","1.0.0":"2017-09-09T14:10:47.594Z"},"users":{},"author":{"name":"Phil Booth","email":"pmbooth@gmail.com","url":"https://philbooth.me/"},"repository":{"type":"git","url":"git+https://gitlab.com/philbooth/tryer.git"},"versions":{"1.0.1":{"name":"tryer","version":"1.0.1","description":"Because everyone loves a tryer! Conditional and repeated task invocation for node and browser.","homepage":"https://gitlab.com/philbooth/tryer","bugs":{"url":"https://gitlab.com/philbooth/tryer/issues"},"license":"MIT","author":{"name":"Phil Booth","email":"pmbooth@gmail.com","url":"https://philbooth.me/"},"main":"./src/tryer","repository":{"type":"git","url":"git+https://gitlab.com/philbooth/tryer.git"},"keywords":["repeat","retry","predicate","conditional","invocation","execution","loop","condition","termination","exponential","backoff"],"devDependencies":{"chai":"4.1.x","jshint":"2.9.x","mocha":"5.2.x","please-release-me":"2.0.x","spooks":"2.0.x","uglify-js":"3.4.x"},"scripts":{"lint":"jshint src/tryer.js test/unit.js","test":"mocha --ui tdd --reporter spec --colors test/unit.js","minify":"uglifyjs ./src/tryer.js --compress --mangle --output ./lib/tryer.min.js"},"contributors":[{"name":"Phil Booth","email":"pmbooth@gmail.com","url":"https://philbooth.me/"},{"name":"Andrew Lawson","url":"https://github.com/adlawson"},{"name":"Tim O'Sulg","url":"https://github.com/timgluz"}],"gitHead":"0ded48c506a02646126f65673953c5e93a89798c","_id":"tryer@1.0.1","_npmVersion":"6.1.0","_nodeVersion":"8.11.1","_npmUser":{"name":"philbooth","email":"pmbooth@gmail.com"},"dist":{"shasum":"f2c85406800b9b0f74c9f7465b81eaad241252f8","size":8793,"noattachment":false,"key":"/tryer/-/tryer-1.0.1.tgz","tarball":"http://registry.cnpm.dingdandao.com/tryer/download/tryer-1.0.1.tgz"},"maintainers":[{"name":"philbooth","email":"pmbooth@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/tryer_1.0.1_1529826573933_0.5249023684379379"},"_hasShrinkwrap":false,"publish_time":1529826573998,"_cnpm_publish_time":1529826573998},"1.0.0":{"name":"tryer","version":"1.0.0","description":"Because everyone loves a tryer! Conditional and repeated task invocation for node and browser.","homepage":"https://github.com/philbooth/tryer","bugs":{"url":"https://github.com/philbooth/tryer/issues"},"license":"MIT","author":{"name":"Phil Booth","email":"pmbooth@gmail.com","url":"https://philbooth.me/"},"main":"./src/tryer","repository":{"type":"git","url":"https://github.com/philbooth/tryer.git"},"keywords":["repeat","retry","predicate","conditional","invocation","execution","loop","condition","termination","exponential","backoff"],"devDependencies":{"chai":"4.1.x","jshint":"2.9.x","mocha":"3.5.x","please-release-me":"1.0.x","spooks":"2.0.x","uglify-js":"3.0.x"},"scripts":{"lint":"jshint src/tryer.js test/unit.js","test":"mocha --ui tdd --reporter spec --colors test/unit.js","minify":"uglifyjs ./src/tryer.js --compress --mangle --output ./lib/tryer.min.js"},"contributors":[{"name":"Phil Booth","email":"pmbooth@gmail.com","url":"https://github.com/philbooth"},{"name":"Andrew Lawson","url":"https://github.com/adlawson"},{"name":"Tim O'Sulg","url":"https://github.com/timgluz"}],"gitHead":"7a0a34b1669e2cc565939c12904178475d39317f","_id":"tryer@1.0.0","_shasum":"027b69fa823225e551cace3ef03b11f6ab37c1d7","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.11.2","_npmUser":{"name":"philbooth","email":"pmbooth@gmail.com"},"dist":{"shasum":"027b69fa823225e551cace3ef03b11f6ab37c1d7","size":8723,"noattachment":false,"key":"/tryer/-/tryer-1.0.0.tgz","tarball":"http://registry.cnpm.dingdandao.com/tryer/download/tryer-1.0.0.tgz"},"maintainers":[{"name":"philbooth","email":"pmbooth@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/tryer-1.0.0.tgz_1504966246616_0.6375626302324235"},"directories":{},"publish_time":1504966247594,"_hasShrinkwrap":false,"_cnpm_publish_time":1504966247594}},"readme":"# tryer\n\n[![Build status](https://gitlab.com/philbooth/tryer/badges/master/pipeline.svg)](https://gitlab.com/philbooth/tryer/pipelines)\n[![Package status](https://img.shields.io/npm/v/tryer.svg)](https://www.npmjs.com/package/tryer)\n[![Downloads](https://img.shields.io/npm/dm/tryer.svg)](https://www.npmjs.com/package/tryer)\n[![License](https://img.shields.io/npm/l/tryer.svg)](https://opensource.org/licenses/MIT)\n\n\nBecause everyone loves a tryer!\nConditional\nand repeated\nfunction invocation\nfor node\nand browser.\n\n* [Say what?](#say-what)\n* [What size is it?](#what-size-is-it)\n* [How do I install it?](#how-do-i-install-it)\n* [How do I use it?](#how-do-i-use-it)\n  * [Loading the library](#loading-the-library)\n  * [Calling the exported function](#calling-the-exported-function)\n  * [Examples](#examples)\n* [How do I set up the dev environment?](#how-do-i-set-up-the-dev-environment)\n* [What license is it released under?](#what-license-is-it-released-under)\n\n## Say what?\n\nSometimes,\nyou want to defer\ncalling a function\nuntil a certain\npre-requisite condition is met.\nOther times,\nyou want to\ncall a function\nrepeatedly\nuntil some post-requisite condition\nis satisfied.\nOccasionally,\nyou might even want\nto do both\nfor the same function.\n\nTo save you writing\nexplicit conditions\nand loops\non each of those occasions,\n`tryer` implements\na predicate-based approach\nthat hides the cruft\nbehind a simple,\nfunctional interface.\n\nAdditionally,\nit allows you to easily specify\nretry intervals\nand limits,\nso that your code\ndoesn't hog the CPU.\nIt also supports\nexponential backoff\nof retry intervals,\nwhich can be useful\nwhen handling\nindefinite error states\nsuch as network failure.\n\n## What size is it?\n\n5.6 kb unminified with comments, 1.1 kb minified, 0.5 kb minified + gzipped.\n\n## How do I install it?\n\nVia npm:\n\n```\nnpm i tryer --save\n```\n\nOr if you just want the git repo:\n\n```\ngit clone git@gitlab.com:philbooth/tryer.git\n```\n\n## How do I use it?\n\n### Loading the library\n\nIf you are running in\nNode.js\nor another CommonJS-style\nenvironment,\nyou can `require`\ntryer like so:\n\n```javascript\nconst tryer = require('tryer');\n```\n\nIt also the supports\nthe AMD-style format\npreferred by Require.js.\n\nIf you are\nincluding `tryer`\nwith an HTML `<script>` tag,\nor neither of the above environments\nare detected,\nit will be exported globally as `tryer`.\n\n### Calling the exported function\n\n`tryer` is a function\nthat can be invoked to\ncall other functions\nconditionally and repeatedly,\nwithout the need for\nexplicit `if` statements\nor loops in your own code.\n\n`tryer` takes one argument,\nan options object\nthat supports\nthe following properties:\n\n* `action`:\n  The function that you want to invoke.\n  If `action` returns a promise,\n  iterations will not end\n  until the promise is resolved or rejected.\n  Alternatively,\n  `action` may take a callback argument, `done`,\n  to signal that it is asynchronous.\n  In that case,\n  you are responsible\n  for calling `done`\n  when the action is finished.\n  If `action` is not set,\n  it defaults to an empty function.\n\n* `when`:\n  A predicate\n  that tests the pre-condition\n  for invoking `action`.\n  Until `when` returns true\n  (or a truthy value),\n  `action` will not be called.\n  Defaults to\n  a function that immediately returns `true`.\n\n* `until`:\n  A predicate\n  that tests the post-condition\n  for invoking `action`.\n  After `until` returns true\n  (or a truthy value),\n  `action` will no longer be called.\n  Defaults to\n  a function that immediately returns `true`.\n\n* `fail`:\n  The error handler.\n  A function\n  that will be called\n  if `limit` falsey values\n  are returned by `when` or `until`.\n  Defaults to an empty function.\n\n* `pass`:\n  Success handler.\n  A function\n  that will be called\n  after `until` has returned truthily.\n  Defaults to an empty function.\n\n* `limit`:\n  Failure limit,\n  representing the maximum number\n  of falsey returns from `when` or `until`\n  that will be permitted\n  before invocation is deemed to have failed.\n  A negative number\n  indicates that the attempt\n  should never fail,\n  instead continuing \n  for as long as `when` and `until`\n  have returned truthy values.\n  Defaults to `-1`.\n\n* `interval`:\n  The retry interval,\n  in milliseconds.\n  A negative number indicates\n  that each subsequent retry\n  should wait for twice the interval\n  from the preceding iteration\n  (i.e. exponential backoff).\n  The default value is `-1000`,\n  signifying that\n  the initial retry interval\n  should be one second\n  and that each subsequent attempt\n  should wait for double the length\n  of the previous interval.\n\n### Examples\n\n```javascript\n// Attempt to insert a database record, waiting until `db.isConnected`\n// before doing so. The retry interval is 1 second on each iteration\n// and the call will fail after 10 attempts.\ntryer({\n  action: () => db.insert(record),\n  when: () => db.isConnected,\n  interval: 1000,\n  limit: 10,\n  fail () {\n    log.error('No database connection, terminating.');\n    process.exit(1);\n  }\n});\n```\n\n```javascript\n// Attempt to send an email message, optionally retrying with\n// exponential backoff starting at 1 second. Continue to make\n// attempts indefinitely until the call succeeds.\nlet sent = false;\ntryer({\n  action (done) {\n    smtp.send(email, error => {\n      if (! error) {\n        sent = true;\n      }\n      done();\n    });\n  },\n  until: () => sent,\n  interval: -1000,\n  limit: -1\n});\n```\n\n```javascript\n// Poll a device at 30-second intervals, continuing indefinitely.\ntryer({\n  action: () => device.poll().then(response => handle(response)),\n  interval: 30000,\n  limit: -1\n});\n```\n\n## How do I set up the dev environment?\n\nThe dev environment relies on\n[Chai],\n[JSHint],\n[Mocha],\n[please-release-me],\n[spooks.js] and\n[UglifyJS].\nThe source code is in\n`src/tryer.js`\nand the unit tests are in\n`test/unit.js`.\n\nTo install the dependencies:\n\n```\nnpm i\n```\n\nTo run the tests:\n\n```\nnpm t\n```\n\nTo lint the code:\n\n```\nnpm run lint\n```\n\nTo regenerate the minified lib:\n\n```\nnpm run minify\n```\n\n## What license is it released under?\n\n[MIT](COPYING)\n\n[chai]: http://chaijs.com/\n[jshint]: http://jshint.com/\n[mocha]: http://mochajs.org/\n[please-release-me]: https://gitlab.com/philbooth/please-release-me\n[spooks.js]: https://gitlab.com/philbooth/spooks.js\n[uglifyjs]: http://lisperator.net/uglifyjs/\n[license]: COPYING\n\n","_attachments":{},"homepage":"https://gitlab.com/philbooth/tryer","bugs":{"url":"https://gitlab.com/philbooth/tryer/issues"},"license":"MIT"}