11import B from 'bluebird' ;
22import _ from 'lodash' ;
3+ import type { LongSleepOptions , WaitForConditionOptions } from './types.js' ;
34
45const LONG_SLEEP_THRESHOLD = 5000 ; // anything over 5000ms will turn into a spin
56
67/**
78 * An async/await version of setTimeout
8- * @param {number } ms
9- * @returns {Promise<void> }
109 */
11- async function sleep ( ms ) {
10+ export async function sleep ( ms : number ) : Promise < void > {
1211 return await B . delay ( ms ) ;
1312}
1413
@@ -17,24 +16,20 @@ async function sleep (ms) {
1716 * times. To safely wait for these long times (e.g. in the 5+ minute range), you
1817 * can use `longSleep`.
1918 *
20- * sYou can also pass a `progressCb` option which is a callback function that
19+ * You can also pass a `progressCb` option which is a callback function that
2120 * receives an object with the properties `elapsedMs`, `timeLeft`, and
2221 * `progress`. This will be called on every wait interval so you can do your
2322 * wait logging or whatever.
24- * @param {number } ms
25- * @param {LongSleepOptions } [opts]
26- * @returns {Promise<void> }
2723 */
28- async function longSleep ( ms , {
29- thresholdMs = LONG_SLEEP_THRESHOLD ,
30- intervalMs = 1000 ,
31- progressCb = null ,
32- } = { } ) {
24+ export async function longSleep (
25+ ms : number ,
26+ { thresholdMs = LONG_SLEEP_THRESHOLD , intervalMs = 1000 , progressCb = null } : LongSleepOptions = { } ,
27+ ) : Promise < void > {
3328 if ( ms < thresholdMs ) {
3429 return await sleep ( ms ) ;
3530 }
3631 const endAt = Date . now ( ) + ms ;
37- let timeLeft ;
32+ let timeLeft : number ;
3833 let elapsedMs = 0 ;
3934 do {
4035 const pre = Date . now ( ) ;
@@ -50,16 +45,15 @@ async function longSleep (ms, {
5045
5146/**
5247 * An async/await way of running a method until it doesn't throw an error
53- * @template [T=any]
54- * @param {number } times
55- * @param {(...args: any[]) => Promise<T> } fn
56- * @param {...any } args
57- * @returns {Promise<T?> }
5848 */
59- async function retry ( times , fn , ...args ) {
49+ export async function retry < T = any > (
50+ times : number ,
51+ fn : ( ...args : any [ ] ) => Promise < T > ,
52+ ...args : any [ ]
53+ ) : Promise < T | null > {
6054 let tries = 0 ;
6155 let done = false ;
62- let res = null ;
56+ let res : T | null = null ;
6357 while ( ! done && tries < times ) {
6458 tries ++ ;
6559 try {
@@ -77,18 +71,17 @@ async function retry (times, fn, ...args) {
7771/**
7872 * You can also use `retryInterval` to add a sleep in between retries. This can
7973 * be useful if you want to throttle how fast we retry.
80- * @template [T=any]
81- * @param {number } times
82- * @param {number } sleepMs
83- * @param {(...args: any[]) => Promise<T> } fn
84- * @param {...any } args
85- * @returns {Promise<T?> }
8674 */
87- async function retryInterval ( times , sleepMs , fn , ...args ) {
75+ export async function retryInterval < T = any > (
76+ times : number ,
77+ sleepMs : number ,
78+ fn : ( ...args : any [ ] ) => Promise < T > ,
79+ ...args : any [ ]
80+ ) : Promise < T | null > {
8881 let count = 0 ;
89- let wrapped = async ( ) => {
82+ const wrapped = async ( ) : Promise < T > => {
9083 count ++ ;
91- let res ;
84+ let res : T ;
9285 try {
9386 res = await fn ( ...args ) ;
9487 } catch ( e ) {
@@ -103,82 +96,78 @@ async function retryInterval (times, sleepMs, fn, ...args) {
10396 return await retry ( times , wrapped ) ;
10497}
10598
106- const parallel = B . all ;
99+ export const parallel = B . all ;
107100
108101/**
109102 * Export async functions (Promises) and import this with your ES5 code to use
110103 * it with Node.
111- * @template [R=any]
112- * @param {any } promisey
113- * @param {(err: any, value?: R) => void } cb
114- * @returns {Promise<R> }
115104 */
116- function nodeify ( promisey , cb ) { // eslint-disable-line promise/prefer-await-to-callbacks
105+ // eslint-disable-next-line promise/prefer-await-to-callbacks
106+ export function nodeify < R = any > ( promisey : any , cb : ( err : any , value ?: R ) => void ) : Promise < R > {
117107 return B . resolve ( promisey ) . nodeify ( cb ) ;
118108}
119109
120110/**
121111 * Node-ify an entire object of `Promise`-returning functions
122- * @param {Record<string,(...args: any[]) => any> } promiseyMap
123- * @returns {Record<string,(...args: any[])=>void> }
124112 */
125- function nodeifyAll ( promiseyMap ) {
126- /** @type {Record<string,(...args: any[])=>void> } */
127- let cbMap = { } ;
113+ export function nodeifyAll < T extends Record < string , ( ...args : any [ ] ) => any > > (
114+ promiseyMap : T ,
115+ ) : Record < string , ( ...args : any [ ] ) => void > {
116+ const cbMap : Record < string , ( ...args : any [ ] ) => void > = { } ;
128117 for ( const [ name , fn ] of _ . toPairs ( promiseyMap ) ) {
129- cbMap [ name ] = function ( ...args ) {
130- const _cb = args . slice ( - 1 ) [ 0 ] ;
131- args = args . slice ( 0 , - 1 ) ;
132- nodeify ( fn ( ...args ) , _cb ) ;
118+ cbMap [ name ] = function ( ...args : any [ ] ) {
119+ const _cb = args . slice ( - 1 ) [ 0 ] as ( err : any , ... values : any [ ] ) => void ;
120+ const fnArgs = args . slice ( 0 , - 1 ) ;
121+ nodeify ( fn ( ...fnArgs ) , _cb ) ;
133122 } ;
134123 }
135124 return cbMap ;
136125}
137126
138127/**
139- * @param {(...args: any[]) => any|Promise<any> } fn
140- * @param {...any } args
128+ * Fire and forget async function execution
141129 */
142- function asyncify ( fn , ...args ) {
130+ export function asyncify ( fn : ( ... args : any [ ] ) => any | Promise < any > , ...args : any [ ] ) : void {
143131 B . resolve ( fn ( ...args ) ) . done ( ) ;
144132}
145133
146134/**
147- * Similar to `Array.prototype.map`; runs in serial
148- * @param {any[] } coll
149- * @param {(value: any) => any|Promise<any> } mapper
150- * @returns {Promise<any[]> }
135+ * Similar to `Array.prototype.map`; runs in serial or parallel
151136 */
152- async function asyncmap ( coll , mapper , runInParallel = true ) {
137+ export async function asyncmap < T , R > (
138+ coll : T [ ] ,
139+ mapper : ( value : T ) => R | Promise < R > ,
140+ runInParallel = true ,
141+ ) : Promise < R [ ] > {
153142 if ( runInParallel ) {
154143 return parallel ( coll . map ( mapper ) ) ;
155144 }
156145
157- let newColl = [ ] ;
158- for ( let item of coll ) {
146+ const newColl : R [ ] = [ ] ;
147+ for ( const item of coll ) {
159148 newColl . push ( await mapper ( item ) ) ;
160149 }
161150 return newColl ;
162151}
163152
164153/**
165154 * Similar to `Array.prototype.filter`
166- * @param {any[] } coll
167- * @param {(value: any) => any|Promise<any> } filter
168- * @param {boolean } runInParallel
169- * @returns {Promise<any[]> }
170155 */
171- async function asyncfilter ( coll , filter , runInParallel = true ) {
172- let newColl = [ ] ;
156+ export async function asyncfilter < T > (
157+ coll : T [ ] ,
158+ filter : ( value : T ) => boolean | Promise < boolean > ,
159+ runInParallel = true ,
160+ ) : Promise < T [ ] > {
161+ const newColl : T [ ] = [ ] ;
173162 if ( runInParallel ) {
174- let bools = await parallel ( coll . map ( filter ) ) ;
163+ const bools = await parallel ( coll . map ( filter ) ) ;
175164 for ( let i = 0 ; i < coll . length ; i ++ ) {
176165 if ( bools [ i ] ) {
177166 newColl . push ( coll [ i ] ) ;
178167 }
179168 }
180169 } else {
181- for ( let item of coll ) {
170+ for ( const item of coll ) {
182171 if ( await filter ( item ) ) {
183172 newColl . push ( item ) ;
184173 }
@@ -199,23 +188,20 @@ async function asyncfilter (coll, filter, runInParallel = true) {
199188 * error then this exception will be immediately passed through.
200189 *
201190 * The default options are: `{ waitMs: 5000, intervalMs: 500 }`
202- * @template T
203- * @param {() => Promise<T>|T } condFn
204- * @param {WaitForConditionOptions } [options]
205- * @returns {Promise<T> }
206191 */
207- async function waitForCondition ( condFn , options = { } ) {
208- /** @type {WaitForConditionOptions & {waitMs: number, intervalMs: number} } */
209- const opts = _ . defaults ( options , {
192+ export async function waitForCondition < T > (
193+ condFn : ( ) => Promise < T > | T ,
194+ options : WaitForConditionOptions = { } ,
195+ ) : Promise < T > {
196+ const opts : WaitForConditionOptions & { waitMs : number ; intervalMs : number } = _ . defaults ( options , {
210197 waitMs : 5000 ,
211198 intervalMs : 500 ,
212199 } ) ;
213200 const debug = opts . logger ? opts . logger . debug . bind ( opts . logger ) : _ . noop ;
214201 const error = opts . error ;
215202 const begunAt = Date . now ( ) ;
216203 const endAt = begunAt + opts . waitMs ;
217- /** @returns {Promise<T> } */
218- const spin = async function spin ( ) {
204+ const spin = async function spin ( ) : Promise < T > {
219205 const result = await condFn ( ) ;
220206 if ( result ) {
221207 return result ;
@@ -230,45 +216,10 @@ async function waitForCondition (condFn, options = {}) {
230216 }
231217 // if there is an error option, it is either a string message or an error itself
232218 throw error
233- ? ( _ . isString ( error ) ? new Error ( error ) : error )
219+ ? _ . isString ( error )
220+ ? new Error ( error )
221+ : error
234222 : new Error ( `Condition unmet after ${ waited } ms. Timing out.` ) ;
235223 } ;
236224 return await spin ( ) ;
237225}
238-
239- export {
240- sleep , retry , nodeify , nodeifyAll , retryInterval , asyncify , parallel ,
241- asyncmap , asyncfilter , waitForCondition , longSleep ,
242- } ;
243-
244- /**
245- * Options for {@link waitForCondition}
246- * @typedef WaitForConditionOptions
247- * @property {number } [waitMs]
248- * @property {number } [intervalMs]
249- * @property {{debug: (...args: any[]) => void} } [logger]
250- * @property {string|Error } [error]
251- */
252-
253- /**
254- * Options for {@link longSleep}
255- * @typedef LongSleepOptions
256- * @property {number } [thresholdMs]
257- * @property {number } [intervalMs]
258- * @property {ProgressCallback? } [progressCb]
259- */
260-
261- /**
262- * Parameter provided to a {@link ProgressCallback}
263- * @typedef Progress
264- * @property {number } elapsedMs
265- * @property {number } timeLeft
266- * @property {number } progress
267- */
268-
269- /**
270- * Progress callback for {@link longSleep}
271- * @callback ProgressCallback
272- * @param {Progress } progress
273- * @returns {void }
274- */
0 commit comments