diff options
author | Elizabeth Alexander Hunt <me@liz.coffee> | 2025-05-12 09:40:12 -0700 |
---|---|---|
committer | Elizabeth Alexander Hunt <me@liz.coffee> | 2025-05-12 09:54:58 -0700 |
commit | 723fa00cb14513eb1a517728d4464c4f148a29cc (patch) | |
tree | d32e2f725397d41b3ad7f886d61c16458dde5b37 /utils/trace.ts | |
parent | 30729a0cf707d9022bae0a7baaba77379dc31fd5 (diff) | |
download | ci-723fa00cb14513eb1a517728d4464c4f148a29cc.tar.gz ci-723fa00cb14513eb1a517728d4464c4f148a29cc.zip |
The big refactor
Diffstat (limited to 'utils/trace.ts')
-rw-r--r-- | utils/trace.ts | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/utils/trace.ts b/utils/trace.ts new file mode 100644 index 0000000..737aa60 --- /dev/null +++ b/utils/trace.ts @@ -0,0 +1,111 @@ +export interface Logger { + log: (...args: unknown[]) => void; + debug: (...args: unknown[]) => void; + warn: (...args: unknown[]) => void; + error: (...args: unknown[]) => void; +} + +type Supplier<T> = () => T; +type TraceSupplier = Supplier<string>; +export interface ITraceableLogger<L extends ITraceableLogger<L>> + extends Logger { + addTracer: (traceSupplier: TraceSupplier) => L; +} + +export type ITraceableTuple<T> = [T, TraceSupplier]; +export type ITraceableMapper<T, L extends ITraceableLogger<L>, U> = ( + t: ITraceable<T, L>, +) => U; +export interface ITraceable<T, L extends ITraceableLogger<L>> { + item: T; + logger: L; + + map: <U>(mapper: ITraceableMapper<T, L, U>) => ITraceable<U, L>; + bimap: <U>( + mapper: ITraceableMapper<T, L, ITraceableTuple<U>>, + ) => ITraceable<U, L>; + peek: (peek: ITraceableMapper<T, L, void>) => ITraceable<T, L>; + flatMap: <U>(mapper: ITraceableMapper<T, L, ITraceable<U, L>>) => ITraceable<U, L>; + flatMapAsync<U>(mapper: ITraceableMapper<T, L, Promise<ITraceable<U, L>>>): ITraceable<Promise<U>, L>; +} + +export class TraceableLogger + implements ITraceableLogger<TraceableLogger> { + private readonly logger: Logger = console; + constructor( + private readonly traces = [() => `[${new Date().toISOString()}]`], + ) { + } + + public debug(...args: unknown[]) { + this.logger.debug("[DEBUG]", ...this.getPrefix(), args); + } + + public log(...args: unknown[]) { + this.logger.log("[INFO]", ...this.getPrefix(), args); + } + + public warn(...args: unknown[]) { + this.logger.warn("[WARN]", ...this.getPrefix(), args); + } + + public error(...args: unknown[]) { + this.logger.error("[ERROR]", ...this.getPrefix(), args); + } + + public addTracer(traceSupplier: TraceSupplier) { + return new TraceableLogger(this.traces.concat(traceSupplier)); + } + + private getPrefix() { + return this.traces.map((tracer) => tracer()); + } +} + +export class TraceableImpl< + T, + L extends ITraceableLogger<L>, +> implements ITraceable<T, L> { + private constructor(readonly item: T, readonly logger: L) {} + + public map<U>(mapper: ITraceableMapper<T, L, U>) { + const result = mapper(this); + return new TraceableImpl(result, this.logger); + } + + public flatMap<U>(mapper: ITraceableMapper<T, L, ITraceable<U, L>>): ITraceable<U, L> { + return mapper(this); + } + + public flatMapAsync<U>(mapper: ITraceableMapper<T, L, Promise<ITraceable<U, L>>>): ITraceable<Promise<U>, L> { + return new TraceableImpl(mapper(this).then((i) => ) + } + + public peek(peek: ITraceableMapper<T, L, void>) { + peek(this); + return this; + } + + public bimap<U>(mapper: ITraceableMapper<T, L, ITraceableTuple<U>>) { + const [item, trace] = mapper(this); + return new TraceableImpl(item, this.logger.addTracer(trace)); + } + + static promiseify<T, L extends ITraceableLogger<L>, U>( + mapper: ITraceableMapper<T, L, U>, + ): ITraceableMapper<Promise<T>, L, Promise<U>> { + return (traceablePromise) => traceablePromise.map( + async ({ item: promise }) => { + const t = await promise; + return traceablePromise.map(() => t).map(mapper).item; + }); +// return (traceable) => +// traceable.item.then((item) => mapper(new TraceableImpl(item, traceable.logger))); + } + + static from<T>(t: T) { + return new TraceableImpl(t, new TraceableLogger()); + } +} + +export interface Traceable<T> extends ITraceable<T, TraceableLogger> |