{"_id":"proggy","_rev":"4130888","name":"proggy","description":"Progress bar updates at a distance","dist-tags":{"latest":"4.0.0"},"maintainers":[{"name":"gar","email":""},{"name":"npm-cli-ops","email":""},{"name":"owlstronaut","email":""},{"name":"reggi","email":""},{"name":"saquibkhan","email":""}],"time":{"modified":"2026-03-01T18:33:05.000Z","created":"2021-09-16T23:08:55.153Z","4.0.0":"2025-10-22T15:28:11.266Z","3.0.0":"2024-09-24T19:19:57.153Z","2.0.0":"2022-10-14T05:22:54.752Z","1.0.0":"2022-02-23T18:58:40.337Z","0.0.1":"2021-09-16T23:08:55.153Z"},"users":{},"author":{"name":"GitHub Inc."},"repository":{"type":"git","url":"git+https://github.com/npm/proggy.git"},"versions":{"4.0.0":{"name":"proggy","version":"4.0.0","main":"lib/index.js","description":"Progress bar updates at a distance","repository":{"type":"git","url":"git+https://github.com/npm/proggy.git"},"author":{"name":"GitHub Inc."},"license":"ISC","scripts":{"test":"tap","posttest":"npm run lint","snap":"tap","postsnap":"eslint lib test --fix","lint":"npm run eslint","postlint":"template-oss-check","lintfix":"npm run eslint -- --fix","template-oss-apply":"template-oss-apply --force","eslint":"eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\""},"devDependencies":{"@npmcli/eslint-config":"^5.0.0","@npmcli/template-oss":"4.27.1","chalk":"^4.1.2","cli-progress":"^3.10.0","npmlog":"^7.0.0","tap":"^16.0.1"},"tap":{"coverage-map":"map.js","nyc-arg":["--exclude","tap-snapshots/**"]},"engines":{"node":"^20.17.0 || >=22.9.0"},"templateOSS":{"//@npmcli/template-oss":"This file is partially managed by @npmcli/template-oss. Edits may be overwritten.","version":"4.27.1","publish":true},"gitHead":"620428d3d68df07d0151e70a35c93c0f5ee6b279","_id":"proggy@4.0.0","bugs":{"url":"https://github.com/npm/proggy/issues"},"homepage":"https://github.com/npm/proggy#readme","_nodeVersion":"22.20.0","_npmVersion":"11.6.2","dist":{"shasum":"85fa89d7c81bc3fb77992a80f47bb1e17c610fa3","size":5005,"noattachment":false,"key":"/proggy/-/proggy-4.0.0.tgz","tarball":"http://registry.cnpm.dingdandao.com/proggy/download/proggy-4.0.0.tgz"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:0ebac37f-89ee-44f9-8dd5-a643054dbb9b"}},"directories":{},"maintainers":[{"name":"gar","email":""},{"name":"npm-cli-ops","email":""},{"name":"owlstronaut","email":""},{"name":"reggi","email":""},{"name":"saquibkhan","email":""}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/proggy_4.0.0_1761146891078_0.011966073052301684"},"_hasShrinkwrap":false,"_cnpmcore_publish_time":"2025-10-22T15:28:11.266Z","publish_time":1761146891266,"_source_registry_name":"default","_cnpm_publish_time":1761146891266},"3.0.0":{"name":"proggy","version":"3.0.0","main":"lib/index.js","description":"Progress bar updates at a distance","repository":{"type":"git","url":"git+https://github.com/npm/proggy.git"},"author":{"name":"GitHub Inc."},"license":"ISC","scripts":{"test":"tap","posttest":"npm run lint","snap":"tap","postsnap":"eslint lib test --fix","lint":"npm run eslint","postlint":"template-oss-check","lintfix":"npm run eslint -- --fix","template-oss-apply":"template-oss-apply --force","eslint":"eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\""},"devDependencies":{"@npmcli/eslint-config":"^5.0.0","@npmcli/template-oss":"4.23.3","chalk":"^4.1.2","cli-progress":"^3.10.0","npmlog":"^7.0.0","tap":"^16.0.1"},"tap":{"coverage-map":"map.js","nyc-arg":["--exclude","tap-snapshots/**"]},"engines":{"node":"^18.17.0 || >=20.5.0"},"templateOSS":{"//@npmcli/template-oss":"This file is partially managed by @npmcli/template-oss. Edits may be overwritten.","version":"4.23.3","publish":true},"_id":"proggy@3.0.0","gitHead":"a2964136f42cc9a29a461fa08c460a9e4b981854","bugs":{"url":"https://github.com/npm/proggy/issues"},"homepage":"https://github.com/npm/proggy#readme","_nodeVersion":"22.9.0","_npmVersion":"10.8.3","dist":{"shasum":"874e91fed27fe00a511758e83216a6b65148bd6c","size":5004,"noattachment":false,"key":"/proggy/-/proggy-3.0.0.tgz","tarball":"http://registry.cnpm.dingdandao.com/proggy/download/proggy-3.0.0.tgz"},"_npmUser":{"name":"npm-cli-ops","email":"npm-cli+bot@github.com"},"directories":{},"maintainers":[{"name":"gar","email":""},{"name":"npm-cli-ops","email":""},{"name":"owlstronaut","email":""},{"name":"reggi","email":""},{"name":"saquibkhan","email":""}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/proggy_3.0.0_1727205596950_0.2202247649843938"},"_hasShrinkwrap":false,"_cnpmcore_publish_time":"2024-09-24T19:19:57.153Z","publish_time":1727205597153,"_source_registry_name":"default","_cnpm_publish_time":1727205597153},"2.0.0":{"name":"proggy","version":"2.0.0","main":"lib/index.js","description":"Progress bar updates at a distance","repository":{"type":"git","url":"git+https://github.com/npm/proggy.git"},"author":{"name":"GitHub Inc."},"license":"ISC","scripts":{"test":"tap","posttest":"npm run lint","snap":"tap","postsnap":"eslint lib test --fix","lint":"eslint \"**/*.js\"","postlint":"template-oss-check","lintfix":"npm run lint -- --fix","template-oss-apply":"template-oss-apply --force"},"devDependencies":{"@npmcli/eslint-config":"^3.0.1","@npmcli/template-oss":"4.5.1","chalk":"^4.1.2","cli-progress":"^3.10.0","npmlog":"^6.0.1","tap":"^16.0.1"},"tap":{"coverage-map":"map.js","nyc-arg":["--exclude","tap-snapshots/**"]},"engines":{"node":"^14.17.0 || ^16.13.0 || >=18.0.0"},"templateOSS":{"//@npmcli/template-oss":"This file is partially managed by @npmcli/template-oss. Edits may be overwritten.","version":"4.5.1"},"gitHead":"4f06e3bba2ffd62b643b96eaa49a43c72b1db57b","bugs":{"url":"https://github.com/npm/proggy/issues"},"homepage":"https://github.com/npm/proggy#readme","_id":"proggy@2.0.0","_nodeVersion":"18.10.0","_npmVersion":"8.19.2","dist":{"shasum":"154bb0e41d3125b518ef6c79782455c2c47d94e1","size":4956,"noattachment":false,"key":"/proggy/-/proggy-2.0.0.tgz","tarball":"http://registry.cnpm.dingdandao.com/proggy/download/proggy-2.0.0.tgz"},"_npmUser":{"name":"lukekarrys","email":"luke@lukekarrys.com"},"directories":{},"maintainers":[{"name":"gar","email":""},{"name":"npm-cli-ops","email":""},{"name":"owlstronaut","email":""},{"name":"reggi","email":""},{"name":"saquibkhan","email":""}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/proggy_2.0.0_1665724974597_0.02894559380025319"},"_hasShrinkwrap":false,"_cnpmcore_publish_time":"2022-11-12T02:56:06.909Z","publish_time":1665724974752,"_cnpm_publish_time":1665724974752},"1.0.0":{"name":"proggy","version":"1.0.0","main":"lib/index.js","description":"Progress bar updates at a distance","repository":{"type":"git","url":"git+https://github.com/npm/proggy.git"},"author":{"name":"GitHub Inc."},"license":"ISC","scripts":{"test":"tap","posttest":"npm run lint","snap":"tap","postsnap":"eslint lib test --fix","preversion":"npm test","postversion":"npm publish","prepublishOnly":"git push origin --follow-tags","lint":"eslint '**/*.js'","postlint":"npm-template-check","template-copy":"npm-template-copy --force","lintfix":"npm run lint -- --fix"},"devDependencies":{"@npmcli/template-oss":"^2.7.1","chalk":"^4.1.2","cli-progress":"^3.10.0","npmlog":"^6.0.1","tap":"^15.1.6"},"tap":{"coverage-map":"map.js"},"engines":{"node":"^12.13.0 || ^14.15.0 || >=16"},"templateOSS":{"version":"2.7.1"},"gitHead":"2b5552c6b39b094f8686fb8cf219bc4fcccdd7be","bugs":{"url":"https://github.com/npm/proggy/issues"},"homepage":"https://github.com/npm/proggy#readme","_id":"proggy@1.0.0","_nodeVersion":"16.14.0","_npmVersion":"8.5.1","dist":{"shasum":"19dc37525e4dac1f3851e9728b6fabf02b11a15d","size":4879,"noattachment":false,"key":"/proggy/-/proggy-1.0.0.tgz","tarball":"http://registry.cnpm.dingdandao.com/proggy/download/proggy-1.0.0.tgz"},"_npmUser":{"name":"lukekarrys","email":"luke@lukekarrys.com"},"directories":{},"maintainers":[{"name":"gar","email":""},{"name":"npm-cli-ops","email":""},{"name":"owlstronaut","email":""},{"name":"reggi","email":""},{"name":"saquibkhan","email":""}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/proggy_1.0.0_1645642720201_0.8138541055740791"},"_hasShrinkwrap":false,"_cnpmcore_publish_time":"2022-02-23T18:58:50.715Z","publish_time":1645642720337,"_cnpm_publish_time":1645642720337},"0.0.1":{"name":"proggy","version":"0.0.1","main":"lib/index.js","description":"Progress bar updates at a distance","repository":{"type":"git","url":"git+https://github.com/npm/proggy.git"},"author":{"name":"Isaac Z. Schlueter","email":"i@izs.me","url":"https://izs.me"},"license":"ISC","scripts":{"test":"tap","posttest":"eslint lib test","snap":"tap","postsnap":"eslint lib test --fix","preversion":"npm test","postversion":"npm publish","prepublishOnly":"git push origin --follow-tags"},"devDependencies":{"chalk":"^2.4.2","cli-progress":"^3.9.0","eslint":"^7.9.0","eslint-plugin-import":"^2.22.0","eslint-plugin-node":"^11.1.0","eslint-plugin-promise":"^4.2.1","eslint-plugin-standard":"^4.0.1","npmlog":"^4.1.2","tap":"^15.0.9"},"tap":{"coverage-map":"map.js"},"gitHead":"f0fab319570b712987c4e7b8b7dc9e2c795ffe23","bugs":{"url":"https://github.com/npm/proggy/issues"},"homepage":"https://github.com/npm/proggy#readme","_id":"proggy@0.0.1","_nodeVersion":"16.5.0","_npmVersion":"7.23.0","dist":{"shasum":"d612f9ab069ed4dab1193ce80e90e2e18c2730b0","size":4823,"noattachment":false,"key":"/proggy/-/proggy-0.0.1.tgz","tarball":"http://registry.cnpm.dingdandao.com/proggy/download/proggy-0.0.1.tgz"},"_npmUser":{"name":"isaacs","email":"i@izs.me"},"directories":{},"maintainers":[{"name":"gar","email":""},{"name":"npm-cli-ops","email":""},{"name":"owlstronaut","email":""},{"name":"reggi","email":""},{"name":"saquibkhan","email":""}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/proggy_0.0.1_1631833734979_0.8028325437868817"},"_hasShrinkwrap":false,"_cnpmcore_publish_time":"2021-12-27T20:45:46.391Z","publish_time":1631833735153,"_cnpm_publish_time":1631833735153}},"readme":"# proggy\n\nProgress bar updates at a distance\n\nA decoupled progress bar connector component that lets you emit events on\nthe process object to provide progress updates from various parts of a\nprogram.\n\n## USAGE\n\nSomewhere in your program, you have a thing that is performing actions that\ntake a while.\n\nIn there, you will emit `progress` events on the global `process` object\nusing Proggy.\n\n```js\nconst proggy = require('proggy')\nconst doSomething = async (listOfItems) => {\n  // This name should be unique within your program.\n  // Proggy will do its best to make sure that you don't create the same\n  // tracker more than once by throwing if you give it a name it's already\n  // seen, but if there are multiple instances of Proggy, it won't be able\n  // to guarantee it.\n  const tracker = proggy.createTracker('doing something')\n  let i = 0\n  for (const item of listOfItems) {\n    tracker.update(i++, listOfItems.length)\n    const result = await doSomething(item)\n\n    // changing the length is allowed!  The progress bar will never go\n    // backwards, but it will slow down if the total increases.\n    if (result.more)\n      listOfItems.push(result.more)\n  }\n  // can either explicitly end, or let it implicitly end when the value\n  // is >= the total.\n  tracker.end()\n}\n```\n\nProggy is not a UI component.  It is a way to decouple the UI of a progress\nbar from the thing that is making the actual progress.\n\nIn another part of your program, where you are handling showing stuff to\nthe user, you can display this information using any of the wonderful\nprogress bar UI modules available on npm.\n\n```js\nconst proggy = require('proggy')\n\n// Create a client that can consume the events emitted elsewhere\nconst client = proggy.createClient()\n```\n\nIf you set the `normalize: true` flag, then the client will normalize how\nfar it thinks the progress should have gone, in order to prevent backwards\nmotion if the length increases along the way.  If using this, then the\n`total` value will always be set to 100, and the `increment` value will\nalways be some number smaller than 100.  Use the `actualValue` and\n`actualTotal` fields to identify how many things have actually been done.\n\nFor example, using\n[`cli-progress`](https://www.npmjs.com/package/cli-progress):\n\n```js\n// set up our display thingmajig\nconst cliProgress = require('cli-progress')\nconst multibar = new cliProgress.MultiBar({\n  clearOnComplete: true,\n  hideCursor: true,\n  // note that data.actualValue and data.actualTotal will reflect the real\n  // done/remaining values.  data.value will always be less than 100, and\n  // data.total will always be 100, so we never show reverse motion.\n  format: '[{bar}] {percentage}% | {name} {actualValue}/{actualTotal} {duration_formatted}',\n  barCompleteChar: '\\u2588',\n  barIncompleteChar: '\\u2591',\n}, cliProgress.Presets.shades_grey)\n\n// update it with events from the proggy client\nconst client = proggy.createClient({\n  // don't show reverse progress\n  // this is false by default\n  normalize: true,\n})\nconst bars = {}\n// new bar is created, tell multibar about it\nclient.on('bar', (key, data) => {\n  bars[key] = multibar.create(data.total)\n})\n// got some progress for a progress bar, tell multibar to show it\nclient.on('progress', (key, data) => {\n  bars[key].update(data.value, data)\n  bars[key].setTotal(data.total)\n})\n// a bar is done, tell multibar to stop updating it\nclient.on('barDone', (key, data) => {\n  bars[key].stop()\n})\n// all bars done, tell multibar to close entirely\nclient.on('done', () => {\n  multibar.stop()\n})\n```\n\n## API\n\n### `proggy.createTracker(name, [key], [total])`\n\nCreate a new `Tracker`.\n\n`key` will default to `name` if not set.  It must be unique.\n\n### `new proggy.Tracker(name, [key], [total])`\n\nThe Tracker class, for emitting progress information.\n\n`total` will default to `100` if not set, but will be updated whenever\nprogress is tracked.\n\n#### Fields\n\n* `name`, `key` - The name and identifer values set in the constructor\n* `done` - `true` if the tracker is completed.\n* `total` `value` - The most recent values updated.\n\n#### `tracker.update(value, total, [metadata])`\n\nUpdate the tracker and emit a `'progress'` event on the `process` object.\n\n#### `tracker.finish([metadata])`\n\nAlias for `tracker.update(tracker.total, tracker.total, metadata)`\n\n### `proggy.createClient(options)`\n\nCreate a new `Client`.\n\n### `new proggy.Client({ normalize = false, stopOnDone = false })`\n\nThe Client class, for consuming progress information.\n\nSet `normalize: true` in the options object to prevent backward motion and\nfix the `total` value at `100`.\n\nSet `stopOnDone: true` in the options object to tell the client to\nautomatically stop when it emits its `'done'` event.\n\n#### Fields\n\n* `normalize` - whether this Client is in normalizing mode\n* `size` - the number of active trackers this Client is aware of\n\n#### Events\n\n* `client.on('bar', (key, data) => {})` - Emitted when a new progress bar\n  is encountered.\n* `client.on('progress', (key, data) => {})` - Emitted when an update is\n  available for a given progress bar.\n* `client.on('barDone', (key, data) => {})` - Emitted when a progress bar\n  is completed.\n* `client.on('done', () => {})` - Emitted when all progress bars are\n  completed.\n\n#### `client.start()`\n\nBegin listening for `'progress'` events on the `process` object.\n\nCalled implicitly if `client.on('progress', fn)` is called.\n\n#### `client.stop()`\n\nStop listening for `'progress'` events on the `process` object.\n\nCalled implicitly when the `'done'` event is emitted, if\n`client.stopOnDone` is true.\n\n#### Progress Data\n\nAll client events receive data objects containing the following fields, in\naddition to whatever else was sent by the `tracker`.\n\n* `key` - The unique key for this progress bar.\n* `name` - The name for this progress bar.\n* `value` - The current value of the progress.  If `client.normalize` is\n  true, then this will always be a number less than `100`, and never reduce\n  from one update to the next.\n* `total` - The expected final value of the progress.  If\n  `client.normalize` is true, then this number will always be `100`.\n* `actualValue` - The value originally sent by the tracker.  If\n  `client.normalize` is not true, then this is always equal to `value`.\n* `actualTotal` - The total originally sent by the tracker.  If\n  `client.normalize` is not true, then this is always equal to `total`.\n* `done` - True if the tracker explicitly sent `done: true` in the data, or\n  if `value` is greater than or equal to `total`.\n* Whatever other fields were set on the `metadata` sent by the tracker.\n","_attachments":{},"homepage":"https://github.com/npm/proggy#readme","bugs":{"url":"https://github.com/npm/proggy/issues"},"license":"ISC"}