summaryrefslogtreecommitdiff
path: root/lib/trace/util.ts
blob: ec67571ff1e3a30a00e2b589435195d88749765b (plain)
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
import {
    IEither,
    IMetric,
    isEither,
    ITraceable,
    ITraceWith,
    LogLevel,
    ResultMetric,
    type Callable,
    type ITraceableMapper,
} from '@emprespresso/pengueno';

export class TraceUtil {
    static promiseify<T, U, Trace>(
        mapper: ITraceableMapper<T, U, Trace>,
    ): ITraceableMapper<Promise<T>, Promise<U>, Trace> {
        return (traceablePromise) =>
            traceablePromise.flatMapAsync(async (t) => t.move(await t.get()).map(mapper)).get();
    }

    static traceResultingEither<TErr, TOk, Trace>(
        metric?: ResultMetric,
        warnOnFailure = false,
    ): ITraceableMapper<IEither<TErr, TOk>, ITraceable<IEither<TErr, TOk>, Trace>, Trace> {
        return (t) => {
            if (metric)
                t.trace.trace(
                    t.get().fold(
                        (_err) => <Trace>(warnOnFailure ? metric.warn : metric.failure),
                        (_ok) => <Trace>metric.success,
                    ),
                );
            return t.traceScope((_t) =>
                _t.get().fold(
                    (_err) => <Trace>(warnOnFailure ? LogLevel.WARN : LogLevel.ERROR),
                    (_ok) => <Trace>LogLevel.INFO,
                ),
            );
        };
    }

    static withTrace<T, Trace, _Trace extends ITraceWith<Trace>>(
        trace: _Trace,
    ): ITraceableMapper<T, ITraceable<T, Trace>, Trace> {
        return (t) => t.traceScope(() => <Trace>trace);
    }

    static withMetricTrace<T, Trace>(metric: IMetric): ITraceableMapper<T, ITraceable<T, Trace>, Trace> {
        return TraceUtil.withTrace(<Trace>metric);
    }

    static withFunctionTrace<F extends Callable, T, Trace>(f: F): ITraceableMapper<T, ITraceable<T, Trace>, Trace> {
        return TraceUtil.withTrace(<Trace>`fn.${f.name}`);
    }

    static withClassTrace<C extends object, T, Trace>(c: C): ITraceableMapper<T, ITraceable<T, Trace>, Trace> {
        return TraceUtil.withTrace(<Trace>`class.${c.constructor.name}`);
    }
}