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
65
66
67
68
69
70
71
|
import {
BaseRequest,
Either,
IEither,
LogMetricTraceable,
Metric,
PenguenoRequest,
Server,
Signals,
TraceUtil,
} from '@emprespresso/pengueno';
import { serve, ServerType } from '@hono/node-server';
import { Hono } from 'hono';
const AppLifetimeMetric = Metric.fromName('HonoAppLifetime').asResult();
const AppRequestMetric = Metric.fromName('HonoAppRequest');
export class HonoProxy {
private readonly app = LogMetricTraceable.of(new Hono())
.flatMap(TraceUtil.withTrace(`AppId = ${crypto.randomUUID()}`))
.flatMap(TraceUtil.withMetricTrace(AppLifetimeMetric));
constructor(private readonly server: Server) {}
public async serve(port: number, hostname: string): Promise<IEither<Error, void>> {
return this.app
.map((tApp) =>
Either.fromFailable<Error, ServerType>(() => {
const app = tApp.get();
app.all('*', async (c) =>
tApp
.flatMap(TraceUtil.withMetricTrace(AppRequestMetric))
.move(<BaseRequest>c.req)
.flatMap((tRequest) => PenguenoRequest.from(tRequest))
.map((req) => this.server.serve(req))
.map(
TraceUtil.promiseify((tResponse) => {
tResponse.trace.trace(AppRequestMetric.count.withValue(1.0));
return new Response(tResponse.get().body(), tResponse.get());
}),
)
.get(),
);
return serve({
fetch: (_r) => app.fetch(_r),
port,
hostname,
});
}),
)
.peek(TraceUtil.traceResultingEither())
.peek((tServe) =>
tServe
.get()
.mapRight(() =>
tServe.trace.trace(
`haii im still listening at http://${hostname}:${port} ~uwu dont think i forgot`,
),
),
)
.map((tEitherServer) =>
tEitherServer
.get()
.mapRight((server) => tEitherServer.move(server))
.flatMapAsync((tServer) => Signals.awaitClose(tServer)),
)
.peek(TraceUtil.promiseify(TraceUtil.traceResultingEither(AppLifetimeMetric)))
.get();
}
}
|