Article URL: https://github.com/nyvexis1/temporize Comments URL: https://news.ycombinator.com/item?id=49143304 Points: 8 # Comments: 4

Small, strongly typed timing and concurrency utilities for modern TypeScript. Every scheduled call returns a real promise for the wrapped function's actual result. There are no runtime dependencies, and the package ships as ESM and CommonJS. temporize deliberately focuses on controlling when and how often work runs. Debouncing, throttling, batching, retry timing, frame scheduling, and idle scheduling all belong to that family. Object, array, string, and other general utility helpers are intentionally out of scope; that boundary is a design decision, not an omission. Several calls coalesced into one invocation each receive a separate promise settled with that invocation's result. A leading-only debounce resolves calls suppressed within the window with the leading invocation's result. Regular throttling coalesces excess calls and uses the latest arguments for a trailing invocation. In browsers, rafThrottle uses requestAnimationFrame. During SSR and in Node, it falls back to a 16 ms setTimeout, so importing and calling it is safe when animation-frame globals do not exist. For typed signal injection, declare a required AbortSignal as the wrapped function's final parameter. debounceAsync removes that parameter from the returned function's call signature. Cancellation is cooperative: an async operation must observe the signal to stop its in-flight work. Every call enters a FIFO queue and starts at least one window after the prior start. The queue limits dispatch rate, not concurrency: a slow promise may still be active when the next window begins. Unlike debounce, batch retains every argument tuple. The wrapped function runs once with the complete array, and every caller in that batch receives the same result or error.