diff options
Diffstat (limited to 'u')
-rw-r--r-- | u/fn/either.ts | 188 | ||||
-rw-r--r-- | u/process/argv.ts | 10 | ||||
-rw-r--r-- | u/server/activity/fourohfour.ts | 9 | ||||
-rw-r--r-- | u/server/request.ts | 11 | ||||
-rw-r--r-- | u/server/response.ts | 10 | ||||
-rw-r--r-- | u/trace/itrace.ts | 46 | ||||
-rw-r--r-- | u/trace/logger.ts | 4 | ||||
-rw-r--r-- | u/trace/metrics.ts | 4 | ||||
-rw-r--r-- | u/trace/trace.ts | 32 |
9 files changed, 158 insertions, 156 deletions
diff --git a/u/fn/either.ts b/u/fn/either.ts index 124557c..bf90f16 100644 --- a/u/fn/either.ts +++ b/u/fn/either.ts @@ -4,115 +4,111 @@ type IEitherTag = "IEither"; const iEitherTag: IEitherTag = "IEither"; export interface _Either<LeftT, RightT, T> { - readonly isLeft: LeftT; - readonly isRight: RightT; - readonly value: T; + readonly isLeft: LeftT; + readonly isRight: RightT; + readonly value: T; } export type Left<E> = _Either<true, false, E>; export type Right<T> = _Either<false, true, T>; export interface IEither<E, T> { - readonly _tag: IEitherTag; - - mapBoth: <_E, _T>( - errBranch: Mapper<E, _E>, - okBranch: Mapper<T, _T>, - ) => IEither<_E, _T>; - fold: <_T>(folder: Mapper<Left<E> | Right<T>, _T>) => _T; - moveRight: <_T>(t: _T) => IEither<E, _T>; - mapRight: <_T>(mapper: Mapper<T, _T>) => IEither<E, _T>; - mapLeft: <_E>(mapper: Mapper<E, _E>) => IEither<_E, T>; - flatMap: <_T>(mapper: Mapper<T, IEither<E, _T>>) => IEither<E, _T>; - flatMapAsync: <_T>( - mapper: Mapper<T, Promise<IEither<E, _T>>>, - ) => Promise<IEither<E, _T>>; + readonly _tag: IEitherTag; + + mapBoth: <_E, _T>( + errBranch: Mapper<E, _E>, + okBranch: Mapper<T, _T>, + ) => IEither<_E, _T>; + fold: <_T>(folder: Mapper<Left<E> | Right<T>, _T>) => _T; + moveRight: <_T>(t: _T) => IEither<E, _T>; + mapRight: <_T>(mapper: Mapper<T, _T>) => IEither<E, _T>; + mapLeft: <_E>(mapper: Mapper<E, _E>) => IEither<_E, T>; + flatMap: <_T>(mapper: Mapper<T, IEither<E, _T>>) => IEither<E, _T>; + flatMapAsync: <_T>( + mapper: Mapper<T, Promise<IEither<E, _T>>>, + ) => Promise<IEither<E, _T>>; } export class Either<E, T> implements IEither<E, T> { - private readonly self: Left<E> | Right<T>; - - private constructor( - err?: E, - ok?: T, - public readonly _tag: IEitherTag = iEitherTag, - ) { - this.self = <Left<E> | Right<T>>{ - isLeft: typeof err !== "undefined", - isRight: typeof ok !== "undefined", - value: typeof err !== "undefined" ? err : ok!, - }; + private readonly self: Left<E> | Right<T>; + + private constructor( + err?: E, + ok?: T, + public readonly _tag: IEitherTag = iEitherTag, + ) { + this.self = <Left<E> | Right<T>>{ + isLeft: typeof err !== "undefined", + isRight: typeof ok !== "undefined", + value: typeof err !== "undefined" ? err : ok!, + }; + } + + public moveRight<_T>(t: _T) { + return this.mapRight(() => t); + } + + public fold<_T>(folder: Mapper<Left<E> | Right<T>, _T>): _T { + return folder(this.self); + } + + public mapBoth<_E, _T>( + errBranch: Mapper<E, _E>, + okBranch: Mapper<T, _T>, + ): IEither<_E, _T> { + if (this.self.isLeft) return Either.left(errBranch(this.self.value)); + return Either.right(okBranch(this.self.value)); + } + + public flatMap<_T>(mapper: Mapper<T, IEither<E, _T>>): IEither<E, _T> { + if (this.self.isRight) return mapper(this.self.value); + return Either.left<E, _T>(this.self.value); + } + + public mapRight<_T>(mapper: Mapper<T, _T>): IEither<E, _T> { + if (this.self.isRight) return Either.right<E, _T>(mapper(this.self.value)); + return Either.left<E, _T>(this.self.value); + } + + public mapLeft<_E>(mapper: Mapper<E, _E>): IEither<_E, T> { + if (this.self.isLeft) return Either.left<_E, T>(mapper(this.self.value)); + return Either.right<_E, T>(this.self.value); + } + + public async flatMapAsync<_T>( + mapper: Mapper<T, Promise<IEither<E, _T>>>, + ): Promise<IEither<E, _T>> { + if (this.self.isLeft) { + return Promise.resolve(Either.left<E, _T>(this.self.value)); } - - public moveRight<_T>(t: _T) { - return this.mapRight(() => t); - } - - public fold<_T>(folder: Mapper<Left<E> | Right<T>, _T>): _T { - return folder(this.self); - } - - public mapBoth<_E, _T>( - errBranch: Mapper<E, _E>, - okBranch: Mapper<T, _T>, - ): IEither<_E, _T> { - if (this.self.isLeft) return Either.left(errBranch(this.self.value)); - return Either.right(okBranch(this.self.value)); - } - - public flatMap<_T>(mapper: Mapper<T, IEither<E, _T>>): IEither<E, _T> { - if (this.self.isRight) return mapper(this.self.value); - return Either.left<E, _T>(this.self.value); - } - - public mapRight<_T>(mapper: Mapper<T, _T>): IEither<E, _T> { - if (this.self.isRight) - return Either.right<E, _T>(mapper(this.self.value)); - return Either.left<E, _T>(this.self.value); - } - - public mapLeft<_E>(mapper: Mapper<E, _E>): IEither<_E, T> { - if (this.self.isLeft) - return Either.left<_E, T>(mapper(this.self.value)); - return Either.right<_E, T>(this.self.value); - } - - public async flatMapAsync<_T>( - mapper: Mapper<T, Promise<IEither<E, _T>>>, - ): Promise<IEither<E, _T>> { - if (this.self.isLeft) { - return Promise.resolve(Either.left<E, _T>(this.self.value)); - } - return await mapper(this.self.value).catch((err) => - Either.left<E, _T>(err), - ); - } - - static left<E, T>(e: E): IEither<E, T> { - return new Either<E, T>(e, undefined); - } - static right<E, T>(t: T): IEither<E, T> { - return new Either<E, T>(undefined, t); - } - - static fromFailable<E, T>(s: Supplier<T>): IEither<E, T> { - try { - return Either.right<E, T>(s()); - } catch (e) { - return Either.left<E, T>(e as E); - } + return await mapper(this.self.value).catch((err) => + Either.left<E, _T>(err), + ); + } + + static left<E, T>(e: E): IEither<E, T> { + return new Either<E, T>(e, undefined); + } + static right<E, T>(t: T): IEither<E, T> { + return new Either<E, T>(undefined, t); + } + + static fromFailable<E, T>(s: Supplier<T>): IEither<E, T> { + try { + return Either.right<E, T>(s()); + } catch (e) { + return Either.left<E, T>(e as E); } + } - static async fromFailableAsync<E, T>( - s: Promise<T>, - ): Promise<IEither<E, T>> { - try { - return Either.right<E, T>(await s); - } catch (e) { - return Either.left<E, T>(e as E); - } + static async fromFailableAsync<E, T>(s: Promise<T>): Promise<IEither<E, T>> { + try { + return Either.right<E, T>(await s); + } catch (e) { + return Either.left<E, T>(e as E); } + } } export const isEither = <E, T>(o: unknown): o is IEither<E, T> => { - return isObject(o) && "_tag" in o && o._tag === "IEither"; + return isObject(o) && "_tag" in o && o._tag === "IEither"; }; diff --git a/u/process/argv.ts b/u/process/argv.ts index 7190531..8e85477 100644 --- a/u/process/argv.ts +++ b/u/process/argv.ts @@ -37,11 +37,11 @@ export const argv = <K extends string, V extends string>( .map((arg) => [arg, getArg(arg, argv)] as [K, IEither<Error, V>]) .map(([arg, specified]): [K, IEither<Error, V>] => [ arg, - specified.fold(({ isLeft, isRight, value}): IEither<Error, V> => { - if (isRight) { - return Either.right(value); - } - const hasDefaultVal = isLeft && defaultArgs && arg in defaultArgs; + specified.fold(({ isLeft, isRight, value }): IEither<Error, V> => { + if (isRight) { + return Either.right(value); + } + const hasDefaultVal = isLeft && defaultArgs && arg in defaultArgs; if (hasDefaultVal) { return Either.right(defaultArgs[arg]!); } diff --git a/u/server/activity/fourohfour.ts b/u/server/activity/fourohfour.ts index ed8c7eb..33cfe5f 100644 --- a/u/server/activity/fourohfour.ts +++ b/u/server/activity/fourohfour.ts @@ -7,12 +7,13 @@ import { } from "@emprespresso/pengueno"; const messages = [ - "D: Meow-t found! Your API call ran away!", - "404-bidden! But like...in a cute way >:3 !", - ":o Your data went on a paw-sible vacation!", + "D: meow-t found! your api call ran away!", + "404-bidden! but like...in a cute way >:3 !", + ":< your data went on a paw-sible vacation!", "uwu~ not found, but found our hearts instead!", ]; -const randomFourOhFour = () => messages[Math.random() * messages.length]; +const randomFourOhFour = () => + messages[Math.floor(Math.random() * messages.length)]; export interface IFourOhFourActivity { fourOhFour: IActivity; diff --git a/u/server/request.ts b/u/server/request.ts index c857f88..5dd9d7b 100644 --- a/u/server/request.ts +++ b/u/server/request.ts @@ -1,4 +1,5 @@ -import { LogMetricTraceable } from "@emprespresso/pengueno"; +import { LogMetricTraceable, LogTraceable } from "@emprespresso/pengueno"; +import { TraceUtil } from "../trace/util.ts"; const greetings = [ "hewwo :D", @@ -39,9 +40,11 @@ export class PenguenoRequest extends Request { const id = crypto.randomUUID(); const url = new URL(request.url); const { pathname } = url; - const traceSupplier = () => `[${id} <- ${request.method}'d @ ${pathname}]`; - return LogMetricTraceable.from( + const logTraceable = LogTraceable.of( new PenguenoRequest(url, { ...request }, id, new Date()), - ).bimap((_request) => [_request.get(), traceSupplier]); + ).bimap( + TraceUtil.withTrace(`Id=${id} Method=${request.method} Path=${pathname}`), + ); + return LogMetricTraceable.ofLogTraceable(logTraceable); } } diff --git a/u/server/response.ts b/u/server/response.ts index 4531157..629dbb5 100644 --- a/u/server/response.ts +++ b/u/server/response.ts @@ -28,12 +28,12 @@ const getResponse = ( }; }; -const ResponseCodeMetrics = [1, 2, 3, 4, 5].map((x) => +const ResponseCodeMetrics = [0, 1, 2, 3, 4, 5].map((x) => Metric.fromName(`response.${x}xx`), ); export const getResponseMetric = (status: number) => { - const index = Math.floor(status / 100) + 1; - return ResponseCodeMetrics[index] ?? ResponseCodeMetrics[5 - 1]; + const index = Math.floor(status / 100); + return ResponseCodeMetrics[index] ?? ResponseCodeMetrics[5]; }; export class PenguenoResponse extends Response { @@ -67,7 +67,9 @@ export class JsonResponse extends PenguenoResponse { super( req, JSON.stringify( - e.fold(({ isLeft, value }) => (isLeft ? { error: value } : { ok: value })), + e.fold(({ isLeft, value }) => + isLeft ? { error: value } : { ok: value }, + ), ), optsWithJsonContentType, ); diff --git a/u/trace/itrace.ts b/u/trace/itrace.ts index ed707c5..35164b5 100644 --- a/u/trace/itrace.ts +++ b/u/trace/itrace.ts @@ -9,29 +9,29 @@ export interface ITrace<TraceWith> { } export type ITraceableTuple<T, TraceWith> = [T, BaseTraceWith | TraceWith]; -export type ITraceableMapper<T, U, TraceWith, W = ITraceable<T, TraceWith>> = ( +export type ITraceableMapper<T, _T, TraceWith, W = ITraceable<T, TraceWith>> = ( w: W, -) => U; +) => _T; export interface ITraceable<T, Trace = BaseTraceWith> { readonly trace: ITrace<Trace>; get: Supplier<T>; - move: <U>(u: U) => ITraceable<U, Trace>; - map: <U>(mapper: ITraceableMapper<T, U, Trace>) => ITraceable<U, Trace>; - bimap: <U>( + move: <_T>(u: _T) => ITraceable<_T, Trace>; + map: <_T>(mapper: ITraceableMapper<T, _T, Trace>) => ITraceable<_T, Trace>; + bimap: <_T>( mapper: ITraceableMapper< T, - ITraceableTuple<U, Array<Trace> | Trace>, + ITraceableTuple<_T, Array<Trace> | Trace>, Trace >, - ) => ITraceable<U, Trace>; + ) => ITraceable<_T, Trace>; peek: (peek: ITraceableMapper<T, void, Trace>) => ITraceable<T, Trace>; - flatMap: <U>( - mapper: ITraceableMapper<T, ITraceable<U, Trace>, Trace>, - ) => ITraceable<U, Trace>; - flatMapAsync<U>( - mapper: ITraceableMapper<T, Promise<ITraceable<U, Trace>>, Trace>, - ): ITraceable<Promise<U>, Trace>; + flatMap: <_T>( + mapper: ITraceableMapper<T, ITraceable<_T, Trace>, Trace>, + ) => ITraceable<_T, Trace>; + flatMapAsync<_T>( + mapper: ITraceableMapper<T, Promise<ITraceable<_T, Trace>>, Trace>, + ): ITraceable<Promise<_T>, Trace>; } export class TraceableImpl<T, TraceWith> implements ITraceable<T, TraceWith> { @@ -40,20 +40,20 @@ export class TraceableImpl<T, TraceWith> implements ITraceable<T, TraceWith> { public readonly trace: ITrace<TraceWith>, ) {} - public map<U>(mapper: ITraceableMapper<T, U, TraceWith>) { + public map<_T>(mapper: ITraceableMapper<T, _T, TraceWith>) { const result = mapper(this); return new TraceableImpl(result, this.trace); } - public flatMap<U>( - mapper: ITraceableMapper<T, ITraceable<U, TraceWith>, TraceWith>, - ): ITraceable<U, TraceWith> { + public flatMap<_T>( + mapper: ITraceableMapper<T, ITraceable<_T, TraceWith>, TraceWith>, + ): ITraceable<_T, TraceWith> { return mapper(this); } - public flatMapAsync<U>( - mapper: ITraceableMapper<T, Promise<ITraceable<U, TraceWith>>, TraceWith>, - ): ITraceable<Promise<U>, TraceWith> { + public flatMapAsync<_T>( + mapper: ITraceableMapper<T, Promise<ITraceable<_T, TraceWith>>, TraceWith>, + ): ITraceable<Promise<_T>, TraceWith> { return new TraceableImpl( mapper(this).then((t) => t.get()), this.trace, @@ -65,14 +65,14 @@ export class TraceableImpl<T, TraceWith> implements ITraceable<T, TraceWith> { return this; } - public move<Tt>(t: Tt): ITraceable<Tt, TraceWith> { + public move<_T>(t: _T): ITraceable<_T, TraceWith> { return this.map(() => t); } - public bimap<U>( + public bimap<_T>( mapper: ITraceableMapper< T, - ITraceableTuple<U, Array<TraceWith> | TraceWith>, + ITraceableTuple<_T, Array<TraceWith> | TraceWith>, TraceWith >, ) { diff --git a/u/trace/logger.ts b/u/trace/logger.ts index 5890545..4f29839 100644 --- a/u/trace/logger.ts +++ b/u/trace/logger.ts @@ -95,8 +95,8 @@ export class LogTrace implements ITrace<LogTraceSupplier> { level: Math.max(logLevelOrder.indexOf(val), acc.level), }; } - const prefix = [acc.line, val].join(" "); - return { ...acc, prefix }; + const line = [acc.line, val].join(" "); + return { ...acc, line }; }, { line: "", level: -1 }, ); diff --git a/u/trace/metrics.ts b/u/trace/metrics.ts index 69322b9..822fc38 100644 --- a/u/trace/metrics.ts +++ b/u/trace/metrics.ts @@ -8,8 +8,8 @@ import { } from "@emprespresso/pengueno"; export enum Unit { - COUNT, - MILLISECONDS, + COUNT = "COUNT", + MILLISECONDS = "MILLISECONDS", } export interface IMetric { diff --git a/u/trace/trace.ts b/u/trace/trace.ts index 03605c2..6cad5b0 100644 --- a/u/trace/trace.ts +++ b/u/trace/trace.ts @@ -1,6 +1,7 @@ import { isMetricsTraceSupplier, type ITrace, + type ITraceable, type ITraceWith, LogTrace, type LogTraceSupplier, @@ -12,16 +13,14 @@ import { export class LogTraceable<T> extends TraceableImpl<T, LogTraceSupplier> { public static LogTrace = new LogTrace(); - static from<T>(t: T) { + static of<T>(t: T) { return new LogTraceable(t, LogTraceable.LogTrace); } } const getEmbeddedMetricConsumer = - (logTrace: LogTrace) => (metrics: Array<MetricValue>) => - logTrace - .addTrace("<metrics>") - .trace(JSON.stringify(metrics, null, 2) + "</metrics>"); + (logTrace: ITrace<LogTraceSupplier>) => (metrics: Array<MetricValue>) => + logTrace.trace(`<metrics>${JSON.stringify(metrics, null)}</metrics>`); export class EmbeddedMetricsTraceable<T> extends TraceableImpl< T, MetricsTraceSupplier @@ -30,11 +29,8 @@ export class EmbeddedMetricsTraceable<T> extends TraceableImpl< getEmbeddedMetricConsumer(LogTraceable.LogTrace), ); - static from<T>(t: T) { - return new EmbeddedMetricsTraceable( - t, - EmbeddedMetricsTraceable.MetricsTrace, - ); + static of<T>(t: T, metricsTrace = EmbeddedMetricsTraceable.MetricsTrace) { + return new EmbeddedMetricsTraceable(t, metricsTrace); } } @@ -72,12 +68,16 @@ export class LogMetricTraceable<T> extends TraceableImpl< T, MetricsTraceSupplier | LogTraceSupplier > { - public static LogMetricTrace = new LogMetricTrace( - LogTraceable.LogTrace, - EmbeddedMetricsTraceable.MetricsTrace, - ); + static ofLogTraceable<T>(t: ITraceable<T, LogTraceSupplier>) { + const metricsTrace = new MetricsTrace(getEmbeddedMetricConsumer(t.trace)); + return new LogMetricTraceable( + t.get(), + new LogMetricTrace(t.trace, metricsTrace), + ); + } - static from<T>(t: T) { - return new LogMetricTraceable(t, LogMetricTraceable.LogMetricTrace); + static of<T>(t: T) { + const logTrace = LogTraceable.of(t); + return LogMetricTraceable.ofLogTraceable(logTrace); } } |