Skip to content

Commit

Permalink
feat(wrappers): expose waitFor wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
uladkasach committed Aug 18, 2024
1 parent 47941a3 commit 920410c
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export * from './checks/isUniDateTime';
export * from './casts/toMillisecondsSinceEpoch';
export * from './manipulate/addDuration';
export * from './manipulate/subDuration';
export * from './wrappers/waitFor';
64 changes: 64 additions & 0 deletions src/wrappers/waitFor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { HelpfulError } from '@ehmpathy/error-fns';
import { NotUndefined, isNotUndefined } from 'type-fns';

import { UniDuration, toMilliseconds } from '../domain/UniDuration';
import { sleep } from '../utils/sleep';

const DEFAULT_TIMEOUT: UniDuration = { seconds: 60 };
const DEFAULT_INTERVAL: UniDuration = { seconds: 10 };

export class WaitForTimedOutError extends HelpfulError {}

/**
* tactic
* .what: wait for an output
* .why:
* - enables waiting until some desired result is ready
* - ensures best practices and a pit of success contract
* - uses readable names for maintainability
*/
export const waitFor = async <O>(
/**
* the procedure which extracts some output that we are waiting for
*
* note
* - waitFor waits until the extractor returns a value other than `void` or `undefined`
*/
extractor: () => Promise<O>,

/**
* options to control the wait
*/
options?: {
/**
* the interval at which to check for completion
*/
interval?: UniDuration;

/**
* the maximum duration to wait for, until timeout
*/
timeout?: UniDuration;
},
): Promise<NotUndefined<O>> => {
// define the timeout and interval
const timeout = options?.timeout ?? DEFAULT_TIMEOUT;
const interval = options?.interval ?? DEFAULT_INTERVAL;

// track the timestamps of interest
const startAtMSE: number = new Date().getTime();
const timeoutAtMSE: number = startAtMSE + toMilliseconds(timeout);

// check each interval
while (new Date().getTime() < timeoutAtMSE) {
const output = await extractor();
if (isNotUndefined(output)) return output;
await sleep(interval);
}

// throw an error if reached here, since it implies a timeout
throw new WaitForTimedOutError('no output returned from waitFor.extractor', {
interval,
timeout,
});
};

0 comments on commit 920410c

Please sign in to comment.