-
Notifications
You must be signed in to change notification settings - Fork 2
/
utils.ts
64 lines (56 loc) · 1.65 KB
/
utils.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import pLimit from "p-limit";
import { Arg } from "./types.ts";
/**
* identity returns the same value as it receives.
*/
export const identity = <T>(val: T): T => {
return val;
};
/**
* withConcurrency returns a wrapped function using the specified concurrency as a limiter.
*/
export const withConcurrency = <TArgs extends Arg = Arg, TResult = unknown>(
concurrency: number,
f: (...args: [...TArgs]) => TResult,
): (...args: [...TArgs]) => Promise<TResult> => {
const limiter = pLimit(concurrency);
return (...args) => {
return limiter(() => f(...args));
};
};
/**
* safeApply applies the given function to the parameter in case of the parameter is not undefined.
*/
export const tryApply =
<T, U>(f: (v: T) => U) => (v: T | undefined): U | undefined => {
return v !== undefined ? f(v) : undefined;
};
/**
* parses the given integer if not undefined.
*/
export const tryParseInt = tryApply(parseInt);
export const tryParseBool = tryApply((v) => v === "true");
export const apply = <T, TResult>(param: T) => (f: (p: T) => TResult) => {
return f(param);
};
interface SingleFlight<T> {
do: (key: string, f: () => Promise<T>) => Promise<T>;
}
export const singleFlight = <T>(): SingleFlight<T> => {
const active: Record<string, Promise<T>> = {};
return {
do: (key: string, f: () => Promise<T>) => {
const promise = active[key];
if (promise !== undefined) {
return promise;
}
active[key] = f().finally(() => delete active[key]);
return active[key];
},
};
};
export function secondsFromNow(seconds: number) {
const date = new Date();
date.setSeconds(date.getSeconds() + seconds);
return date;
}