{"_rev":"4-04a4e0949ad97926be7e43aa0301188b","time":{"created":"2026-07-26T09:23:38.340Z","modified":"2026-07-26T09:23:38.713Z","0.1.0":"2026-07-24T12:42:35.692Z","0.1.1":"2026-07-26T09:23:38.562Z"},"_id":"@azghr/wend","name":"@azghr/wend","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.1":{"name":"@azghr/wend","version":"0.1.1","description":"Poll an async producer until a predicate passes — exponential backoff with jitter, overall timeout, AbortSignal, returns the value","license":"MIT","type":"module","sideEffects":false,"main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"engines":{"node":">=18"},"scripts":{"build":"tsup src/index.ts --format esm,cjs --dts --sourcemap --clean","test":"vitest run","test:watch":"vitest","typecheck":"tsc --noEmit","lint":"eslint src test examples","demo":"tsx examples/demo.ts","check":"npm run typecheck && npm run lint && npm run test && npm run build","prepublishOnly":"npm run check"},"keywords":["poll","wait","retry","backoff","exponential","jitter","timeout","abort","async","promise","condition","predicate"],"devDependencies":{"@eslint/js":"^9.18.0","eslint":"^9.18.0","tsx":"^4.19.2","typescript":"^5.7.3","typescript-eslint":"^8.19.1","vitest":"^2.1.8","tsup":"^8.3.5"},"gitHead":"1ae43506bd10e95719674826afbf0456e95e26f7","_id":"@azghr/wend@0.1.1","_nodeVersion":"24.12.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-Opg+aOqEq+2PPVXkBcj3qfB2kz5lWkVLIwghMOVTFm39GA3mWflt0cQWY22q81wzbVKFBScrM7eN2sLQ7Kk8aA==","shasum":"4de2c973009175906d1d68b9304d9b120d607e0f","tarball":"https://registry.npmjs.org/@azghr/wend/-/wend-0.1.1.tgz","fileCount":10,"unpackedSize":35229,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIE3VCZ2JW6v7F55ntTM5wwiHydQXAi66xqWUnIhwIGozAiB64e8sH0bW2ljb+9pEI7zDrSRNgc6DONWlNoY2ozrcTQ=="}]},"_npmUser":{"name":"azghr","email":"masgharali.eng@gmail.com"},"directories":{},"maintainers":[{"name":"azghr","email":"masgharali.eng@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/wend_0.1.1_1785057818425_0.3891432952677971"},"_hasShrinkwrap":false}},"maintainers":[{"name":"azghr","email":"masgharali.eng@gmail.com"}],"description":"Poll an async producer until a predicate passes — exponential backoff with jitter, overall timeout, AbortSignal, returns the value","keywords":["poll","wait","retry","backoff","exponential","jitter","timeout","abort","async","promise","condition","predicate"],"license":"MIT","readme":"# @azghr/wend\n\n[![npm](https://img.shields.io/npm/v/@azghr/wend)](https://www.npmjs.com/package/@azghr/wend)\n[![MIT License](https://img.shields.io/npm/l/@azghr/wend)](LICENSE)\n\nPoll an async producer until a predicate passes — exponential backoff with jitter, timeout, abort signal, returns the value.\n\n## The problem\n\n\"Wait until the file exists / the pod is ready / the job status is DONE\" — polling a condition with sane intervals, backoff, timeout, and cancellation. Everyone writes a slightly-wrong `setInterval` loop that leaks a timer or ignores AbortSignal.\n\n`p-wait-for` exists and is decent, so this is not an empty category. `wend` earns its place by adding what's commonly missing together: exponential backoff with jitter, a first-class `AbortSignal`, a max-attempts OR max-time bound, and returning the resolved value. If you only need fixed-interval polling, `p-wait-for` is fine.\n\n## Install\n\n```bash\nnpm install @azghr/wend\n# or\npnpm add @azghr/wend\n# or\nyarn add @azghr/wend\n```\n\n## Use\n\nPoll a condition until it passes:\n\n```ts\nimport wend from \"@azghr/wend\";\n\nconst pod = await wend(\n  () => getPod(),\n  (p) => p.ready,\n  { timeoutMs: 30_000 }\n);\n```\n\nWait for file existence with backoff:\n\n```ts\nawait wend(\n  () => fileExists(path),\n  (exists) => exists,\n  { minDelayMs: 100, maxDelayMs: 5000, factor: 2 }\n);\n```\n\n## API\n\n### `wend(produce, predicate, options)`\n\nPoll an async producer until a predicate passes.\n\n```ts\nfunction wend<T>(\n  produce: () => T | Promise<T>,\n  predicate: (value: T) => boolean,\n  options?: WendOptions\n): Promise<T>;\n```\n\n**Options:**\n- `minDelayMs` — First delay in ms (default: 100)\n- `maxDelayMs` — Delay cap in ms (default: 5000)\n- `factor` — Backoff multiplier (default: 2)\n- `jitter` — Apply full jitter (default: true)\n- `timeoutMs` — Overall deadline in ms (default: Infinity)\n- `maxAttempts` — Maximum attempts (default: Infinity)\n- `signal` — AbortSignal for cancellation\n- `now`/`sleep`/`random` — Test injection points\n\n**Throws:** `WendTimeout` (timeout exceeded), `WendExhausted` (max attempts reached), or produces errors immediately (no retry).\n\n### `WendTimeout`, `WendExhausted`\n\nError classes for timeout and max attempts failures.\n\n## Non-goals\n\n`wend` is NOT a retry library, scheduler, or event-based waiter. For transient failures, compose with a retry library. For fixed schedules, use a cron scheduler. For events, use `EventEmitter.once()` or `Promise.race()`.\n\n## Related packages\n\n**Caching & Concurrency:**\n- **[@azghr/filterkit](https://www.npmjs.com/package/@azghr/filterkit)** — Framework-agnostic, type-safe filtering for TypeScript\n- **[@azghr/singlet](https://www.npmjs.com/package/@azghr/singlet)** — Deduplicate concurrent async calls\n- **[staleness](https://www.npmjs.com/package/staleness)** — Stale-while-revalidate caching for async functions\n\n**Text Processing:**\n- **[@azghr/shorn](https://www.npmjs.com/package/@azghr/shorn)** — Truncate strings by byte budget without breaking graphemes\n- **[seriatim](https://www.npmjs.com/package/seriatim)** — Sequential processing utilities\n\n**HTTP & Network:**\n- **[forbear](https://www.npmjs.com/package/forbear)** — Read server rate-limit instructions from HTTP responses\n- **[forestall](https://www.npmjs.com/package/forestall)** — Delay execution until a condition is met\n- **[obviate](https://www.npmjs.com/package/obviate)** — Render operations unnecessary through caching\n\n**System & Process:**\n- **[quiesce](https://www.npmjs.com/package/quiesce)** — Ordered, timeboxed graceful shutdown for Node\n- **[sortition](https://www.npmjs.com/package/sortition)** — Deterministic percentage rollouts and A/B bucketing\n\n**Utilities:**\n- **[expunge](https://www.npmjs.com/package/expunge)** — Remove or exclude items from collections\n- **[occlude](https://www.npmjs.com/package/occlude)** — Hide or mask data and functionality\n- **[placemark](https://www.npmjs.com/package/placemark)** — Geographic location and mapping utilities\n- **[specie](https://www.npmjs.com/package/specie)** — Currency and financial calculations\n\n## License\n\nMIT","readmeFilename":"README.md"}